forked from trent_larson/crowd-funder-for-time-pwa
fix(settings): resolve server switching not applying immediately
- Fix database query logic in PlatformServiceMixin.$getSettings() to properly distinguish between master settings (ID) and account settings (DID) - Add comprehensive logging for settings debugging with request IDs and component tracking - Fix ProfileService initialization order in AccountViewView to use correct partnerApiServer after settings load - Add URL flow testing interface in TestView for debugging server switching - Enhance settings consistency validation and error handling Resolves issue where profile server changes were saved but not applied due to incorrect database query logic and settings priority handling. Files changed: PlatformServiceMixin.ts, AccountViewView.vue, TestView.vue, TopMessage.vue, main.ts, router/index.ts Testing: Added comprehensive URL flow testing interface for validation
This commit is contained in:
@@ -18,6 +18,7 @@ import { Component, Vue, Prop } from "vue-facing-decorator";
|
|||||||
import { AppString, NotificationIface } from "../constants/app";
|
import { AppString, NotificationIface } from "../constants/app";
|
||||||
import { PlatformServiceMixin } from "../utils/PlatformServiceMixin";
|
import { PlatformServiceMixin } from "../utils/PlatformServiceMixin";
|
||||||
import { createNotifyHelpers, TIMEOUTS } from "../utils/notify";
|
import { createNotifyHelpers, TIMEOUTS } from "../utils/notify";
|
||||||
|
import { logger } from "../utils/logger";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
mixins: [PlatformServiceMixin],
|
mixins: [PlatformServiceMixin],
|
||||||
@@ -29,6 +30,7 @@ export default class TopMessage extends Vue {
|
|||||||
// - Cache management: this.$refreshSettings(), this.$clearAllCaches()
|
// - Cache management: this.$refreshSettings(), this.$clearAllCaches()
|
||||||
// - Ultra-concise database methods: this.$db(), this.$exec(), this.$query()
|
// - Ultra-concise database methods: this.$db(), this.$exec(), this.$query()
|
||||||
// - All methods use smart caching with TTL for massive performance gains
|
// - All methods use smart caching with TTL for massive performance gains
|
||||||
|
// - FIXED: Now properly respects database settings without forcing API server overrides
|
||||||
|
|
||||||
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
||||||
|
|
||||||
@@ -42,26 +44,49 @@ export default class TopMessage extends Vue {
|
|||||||
this.notify = createNotifyHelpers(this.$notify);
|
this.notify = createNotifyHelpers(this.$notify);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Ultra-concise cached settings loading - replaces 50+ lines of logic!
|
// Load settings without overriding database values - fixes settings inconsistency
|
||||||
const settings = await this.$accountSettings(undefined, {
|
logger.info("[TopMessage] 📥 Loading settings without overrides...");
|
||||||
activeDid: undefined,
|
const settings = await this.$accountSettings();
|
||||||
apiServer: AppString.PROD_ENDORSER_API_SERVER,
|
|
||||||
|
logger.info("[TopMessage] 📊 Settings loaded:", {
|
||||||
|
activeDid: settings.activeDid,
|
||||||
|
apiServer: settings.apiServer,
|
||||||
|
warnIfTestServer: settings.warnIfTestServer,
|
||||||
|
warnIfProdServer: settings.warnIfProdServer,
|
||||||
|
component: "TopMessage",
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Only show warnings if the user has explicitly enabled them
|
||||||
if (
|
if (
|
||||||
settings.warnIfTestServer &&
|
settings.warnIfTestServer &&
|
||||||
|
settings.apiServer &&
|
||||||
settings.apiServer !== AppString.PROD_ENDORSER_API_SERVER
|
settings.apiServer !== AppString.PROD_ENDORSER_API_SERVER
|
||||||
) {
|
) {
|
||||||
const didPrefix = settings.activeDid?.slice(11, 15);
|
const didPrefix = settings.activeDid?.slice(11, 15);
|
||||||
this.message = "You're not using prod, user " + didPrefix;
|
this.message = "You're not using prod, user " + didPrefix;
|
||||||
|
logger.info("[TopMessage] ⚠️ Test server warning displayed:", {
|
||||||
|
apiServer: settings.apiServer,
|
||||||
|
didPrefix: didPrefix,
|
||||||
|
});
|
||||||
} else if (
|
} else if (
|
||||||
settings.warnIfProdServer &&
|
settings.warnIfProdServer &&
|
||||||
|
settings.apiServer &&
|
||||||
settings.apiServer === AppString.PROD_ENDORSER_API_SERVER
|
settings.apiServer === AppString.PROD_ENDORSER_API_SERVER
|
||||||
) {
|
) {
|
||||||
const didPrefix = settings.activeDid?.slice(11, 15);
|
const didPrefix = settings.activeDid?.slice(11, 15);
|
||||||
this.message = "You are using prod, user " + didPrefix;
|
this.message = "You are using prod, user " + didPrefix;
|
||||||
|
logger.info("[TopMessage] ⚠️ Production server warning displayed:", {
|
||||||
|
apiServer: settings.apiServer,
|
||||||
|
didPrefix: didPrefix,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
logger.debug(
|
||||||
|
"[TopMessage] ℹ️ No warnings displayed - conditions not met",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
|
logger.error("[TopMessage] ❌ Error loading settings:", err);
|
||||||
this.notify.error(JSON.stringify(err), TIMEOUTS.MODAL);
|
this.notify.error(JSON.stringify(err), TIMEOUTS.MODAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ const platform = process.env.VITE_PLATFORM || "web";
|
|||||||
|
|
||||||
logger.info(`[Main] 🚀 Loading TimeSafari for platform: ${platform}`);
|
logger.info(`[Main] 🚀 Loading TimeSafari for platform: ${platform}`);
|
||||||
|
|
||||||
|
// Log all relevant environment variables for boot-time debugging
|
||||||
|
logger.info("[Main] 🌍 Boot-time environment configuration:", {
|
||||||
|
platform: process.env.VITE_PLATFORM,
|
||||||
|
defaultEndorserApiServer: process.env.VITE_DEFAULT_ENDORSER_API_SERVER,
|
||||||
|
defaultPartnerApiServer: process.env.VITE_DEFAULT_PARTNER_API_SERVER,
|
||||||
|
nodeEnv: process.env.NODE_ENV,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
|
||||||
// Dynamically import the appropriate main entry point
|
// Dynamically import the appropriate main entry point
|
||||||
if (platform === "capacitor") {
|
if (platform === "capacitor") {
|
||||||
logger.info(`[Main] 📱 Loading Capacitor-specific entry point`);
|
logger.info(`[Main] 📱 Loading Capacitor-specific entry point`);
|
||||||
|
|||||||
@@ -337,6 +337,22 @@ router.beforeEach(async (to, _from, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Log boot-time configuration on first navigation
|
||||||
|
if (!_from) {
|
||||||
|
logger.info(
|
||||||
|
"[Router] 🚀 First navigation detected - logging boot-time configuration:",
|
||||||
|
{
|
||||||
|
platform: process.env.VITE_PLATFORM,
|
||||||
|
defaultEndorserApiServer:
|
||||||
|
process.env.VITE_DEFAULT_ENDORSER_API_SERVER,
|
||||||
|
defaultPartnerApiServer: process.env.VITE_DEFAULT_PARTNER_API_SERVER,
|
||||||
|
nodeEnv: process.env.NODE_ENV,
|
||||||
|
targetRoute: to.path,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Skip identity check for routes that handle identity creation manually
|
// Skip identity check for routes that handle identity creation manually
|
||||||
const skipIdentityRoutes = [
|
const skipIdentityRoutes = [
|
||||||
"/start",
|
"/start",
|
||||||
|
|||||||
@@ -58,7 +58,10 @@
|
|||||||
v-if="!isRegistered"
|
v-if="!isRegistered"
|
||||||
:passkeys-enabled="PASSKEYS_ENABLED"
|
:passkeys-enabled="PASSKEYS_ENABLED"
|
||||||
:given-name="givenName"
|
:given-name="givenName"
|
||||||
message="Before you can publicly announce a new project or time commitment, a friend needs to register you."
|
:message="
|
||||||
|
`Before you can publicly announce a new project or time commitment, ` +
|
||||||
|
`a friend needs to register you.`
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Notifications -->
|
<!-- Notifications -->
|
||||||
@@ -925,7 +928,10 @@ export default class AccountViewView extends Vue {
|
|||||||
// This prevents the "Cannot read properties of undefined (reading 'Default')" error
|
// This prevents the "Cannot read properties of undefined (reading 'Default')" error
|
||||||
if (L.Icon.Default) {
|
if (L.Icon.Default) {
|
||||||
// Type-safe way to handle Leaflet icon prototype
|
// Type-safe way to handle Leaflet icon prototype
|
||||||
const iconDefault = L.Icon.Default.prototype as Record<string, unknown>;
|
const iconDefault = L.Icon.Default.prototype as unknown as Record<
|
||||||
|
string,
|
||||||
|
unknown
|
||||||
|
>;
|
||||||
if ("_getIconUrl" in iconDefault) {
|
if ("_getIconUrl" in iconDefault) {
|
||||||
delete iconDefault._getIconUrl;
|
delete iconDefault._getIconUrl;
|
||||||
}
|
}
|
||||||
@@ -947,14 +953,25 @@ export default class AccountViewView extends Vue {
|
|||||||
* @throws Will display specific messages to the user based on different errors.
|
* @throws Will display specific messages to the user based on different errors.
|
||||||
*/
|
*/
|
||||||
async mounted(): Promise<void> {
|
async mounted(): Promise<void> {
|
||||||
this.profileService = createProfileService(
|
|
||||||
this.axios,
|
|
||||||
this.partnerApiServer,
|
|
||||||
);
|
|
||||||
try {
|
try {
|
||||||
await this.initializeState();
|
await this.initializeState();
|
||||||
await this.processIdentity();
|
await this.processIdentity();
|
||||||
|
|
||||||
|
// FIXED: Create ProfileService AFTER settings are loaded to get correct partnerApiServer
|
||||||
|
this.profileService = createProfileService(
|
||||||
|
this.axios,
|
||||||
|
this.partnerApiServer,
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"[AccountViewView] ✅ ProfileService created with correct partnerApiServer:",
|
||||||
|
{
|
||||||
|
partnerApiServer: this.partnerApiServer,
|
||||||
|
component: "AccountViewView",
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if (this.isRegistered) {
|
if (this.isRegistered) {
|
||||||
try {
|
try {
|
||||||
const profile = await this.profileService.loadProfile(this.activeDid);
|
const profile = await this.profileService.loadProfile(this.activeDid);
|
||||||
|
|||||||
@@ -91,13 +91,95 @@
|
|||||||
name: 'shared-photo',
|
name: 'shared-photo',
|
||||||
query: { fileName },
|
query: { fileName },
|
||||||
}"
|
}"
|
||||||
class="block w-full text-center text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-2 mt-2"
|
class="block w-full text-center text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-2 mt-2"
|
||||||
data-testId="fileUploadButton"
|
data-testId="fileUploadButton"
|
||||||
>
|
>
|
||||||
Go to Shared Page
|
Go to Shared Page
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- URL Flow Testing Section -->
|
||||||
|
<div class="mt-8">
|
||||||
|
<h2 class="text-xl font-bold mb-4">URL Flow Testing</h2>
|
||||||
|
<p class="text-sm text-gray-600 mb-3">
|
||||||
|
Test claim and partner server URL flow from initialization to change
|
||||||
|
propagation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div class="p-4 border border-gray-300 rounded-md bg-gray-50">
|
||||||
|
<h3 class="font-semibold mb-2">Current URL State</h3>
|
||||||
|
<div class="space-y-2 text-sm">
|
||||||
|
<div>
|
||||||
|
<strong>API Server:</strong>
|
||||||
|
<span class="font-mono">{{ apiServer || "Not Set" }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Partner API Server:</strong>
|
||||||
|
<span class="font-mono">{{ partnerApiServer || "Not Set" }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Active DID:</strong>
|
||||||
|
<span class="font-mono">{{ activeDid || "Not Set" }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Platform:</strong>
|
||||||
|
<span class="font-mono">{{ getCurrentPlatform() }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-2">
|
||||||
|
<button
|
||||||
|
:class="primaryButtonClasses"
|
||||||
|
:disabled="isUrlTestRunning"
|
||||||
|
@click="testUrlFlow()"
|
||||||
|
>
|
||||||
|
{{ isUrlTestRunning ? "Testing..." : "Test URL Flow" }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button :class="secondaryButtonClasses" @click="changeApiServer()">
|
||||||
|
Change API Server (Test → Prod)
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
:class="secondaryButtonClasses"
|
||||||
|
@click="changePartnerApiServer()"
|
||||||
|
>
|
||||||
|
Change Partner API Server (Test → Prod)
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button :class="warningButtonClasses" @click="resetToDefaults()">
|
||||||
|
Reset to Defaults
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button :class="secondaryButtonClasses" @click="refreshSettings()">
|
||||||
|
Refresh Settings
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
:class="secondaryButtonClasses"
|
||||||
|
@click="logEnvironmentState()"
|
||||||
|
>
|
||||||
|
Log Environment State
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 border border-gray-300 rounded-md bg-gray-50">
|
||||||
|
<h3 class="font-semibold mb-2">URL Flow Test Results</h3>
|
||||||
|
<div class="max-h-64 overflow-y-auto space-y-2">
|
||||||
|
<div
|
||||||
|
v-for="(result, index) in urlTestResults"
|
||||||
|
:key="index"
|
||||||
|
class="p-2 border border-gray-200 rounded text-xs font-mono bg-white"
|
||||||
|
>
|
||||||
|
{{ result }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<h2 class="text-xl font-bold mb-4">Passkeys</h2>
|
<h2 class="text-xl font-bold mb-4">Passkeys</h2>
|
||||||
See console for results.
|
See console for results.
|
||||||
@@ -326,6 +408,11 @@ export default class Help extends Vue {
|
|||||||
showEntityGridTest = false;
|
showEntityGridTest = false;
|
||||||
showPlatformServiceTest = false;
|
showPlatformServiceTest = false;
|
||||||
|
|
||||||
|
// for URL flow testing
|
||||||
|
isUrlTestRunning = false;
|
||||||
|
urlTestResults: string[] = [];
|
||||||
|
partnerApiServer: string | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computed properties for template streamlining
|
* Computed properties for template streamlining
|
||||||
* Eliminates repeated classes and logic in template
|
* Eliminates repeated classes and logic in template
|
||||||
@@ -534,24 +621,93 @@ export default class Help extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component initialization
|
|
||||||
*
|
|
||||||
* Loads user settings and account information for testing interface
|
* Loads user settings and account information for testing interface
|
||||||
* Uses PlatformServiceMixin for database access
|
* Uses PlatformServiceMixin for database access
|
||||||
*/
|
*/
|
||||||
async mounted() {
|
async mounted() {
|
||||||
const settings = await this.$accountSettings();
|
logger.info(
|
||||||
this.activeDid = settings.activeDid || "";
|
"[TestView] 🚀 Component mounting - starting URL flow tracking",
|
||||||
this.apiServer = settings.apiServer || "";
|
);
|
||||||
this.userName = settings.firstName;
|
|
||||||
|
|
||||||
const account = await retrieveAccountMetadata(this.activeDid);
|
// Boot-time logging for initial configuration
|
||||||
if (this.activeDid) {
|
logger.info("[TestView] 🌍 Boot-time configuration detected:", {
|
||||||
if (account) {
|
platform: process.env.VITE_PLATFORM,
|
||||||
this.credIdHex = account.passkeyCredIdHex as string;
|
defaultEndorserApiServer: process.env.VITE_DEFAULT_ENDORSER_API_SERVER,
|
||||||
} else {
|
defaultPartnerApiServer: process.env.VITE_DEFAULT_PARTNER_API_SERVER,
|
||||||
alert("No account found for DID " + this.activeDid);
|
nodeEnv: process.env.NODE_ENV,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Track settings loading
|
||||||
|
logger.info("[TestView] 📥 Loading account settings...");
|
||||||
|
const settings = await this.$accountSettings();
|
||||||
|
|
||||||
|
logger.info("[TestView] 📊 Settings loaded:", {
|
||||||
|
activeDid: settings.activeDid,
|
||||||
|
apiServer: settings.apiServer,
|
||||||
|
partnerApiServer: settings.partnerApiServer,
|
||||||
|
isRegistered: settings.isRegistered,
|
||||||
|
firstName: settings.firstName,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update component state
|
||||||
|
this.activeDid = settings.activeDid || "";
|
||||||
|
this.apiServer = settings.apiServer || "";
|
||||||
|
this.partnerApiServer = settings.partnerApiServer || "";
|
||||||
|
this.userName = settings.firstName;
|
||||||
|
|
||||||
|
logger.info("[TestView] ✅ Component state updated:", {
|
||||||
|
activeDid: this.activeDid,
|
||||||
|
apiServer: this.apiServer,
|
||||||
|
partnerApiServer: this.partnerApiServer,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load account metadata
|
||||||
|
if (this.activeDid) {
|
||||||
|
logger.info(
|
||||||
|
"[TestView] 🔍 Loading account metadata for DID:",
|
||||||
|
this.activeDid,
|
||||||
|
);
|
||||||
|
const account = await retrieveAccountMetadata(this.activeDid);
|
||||||
|
|
||||||
|
if (account) {
|
||||||
|
this.credIdHex = account.passkeyCredIdHex as string;
|
||||||
|
logger.info("[TestView] ✅ Account metadata loaded:", {
|
||||||
|
did: account.did,
|
||||||
|
hasPasskey: !!account.passkeyCredIdHex,
|
||||||
|
passkeyId: account.passkeyCredIdHex,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
logger.warn(
|
||||||
|
"[TestView] ⚠️ No account found for DID:",
|
||||||
|
this.activeDid,
|
||||||
|
);
|
||||||
|
alert("No account found for DID " + this.activeDid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info("[TestView] 🎯 Component initialization complete:", {
|
||||||
|
activeDid: this.activeDid,
|
||||||
|
apiServer: this.apiServer,
|
||||||
|
partnerApiServer: this.partnerApiServer,
|
||||||
|
hasPasskey: !!this.credIdHex,
|
||||||
|
platform: this.getCurrentPlatform(),
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(
|
||||||
|
"[TestView] ❌ Error during component initialization:",
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "error",
|
||||||
|
type: "error",
|
||||||
|
title: "Initialization Error",
|
||||||
|
text: `Failed to initialize component: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
},
|
||||||
|
5000,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,5 +980,276 @@ export default class Help extends Vue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the URL flow from initialization to change propagation.
|
||||||
|
* This simulates the flow where a user's DID is set, and then the
|
||||||
|
* claim and partner server URLs are updated.
|
||||||
|
*/
|
||||||
|
public async testUrlFlow() {
|
||||||
|
this.isUrlTestRunning = true;
|
||||||
|
this.urlTestResults = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
logger.info("[TestView] 🔬 Starting comprehensive URL flow test");
|
||||||
|
this.addUrlTestResult("🚀 Starting URL flow test...");
|
||||||
|
|
||||||
|
// Test 1: Current state
|
||||||
|
this.addUrlTestResult(`📊 Current State:`);
|
||||||
|
this.addUrlTestResult(` - API Server: ${this.apiServer || "Not Set"}`);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Partner API Server: ${this.partnerApiServer || "Not Set"}`,
|
||||||
|
);
|
||||||
|
this.addUrlTestResult(` - Active DID: ${this.activeDid || "Not Set"}`);
|
||||||
|
this.addUrlTestResult(` - Platform: ${this.getCurrentPlatform()}`);
|
||||||
|
|
||||||
|
// Test 2: Load fresh settings
|
||||||
|
this.addUrlTestResult(`\n📥 Testing Settings Loading:`);
|
||||||
|
const startTime = Date.now();
|
||||||
|
const settings = await this.$accountSettings();
|
||||||
|
const loadTime = Date.now() - startTime;
|
||||||
|
|
||||||
|
this.addUrlTestResult(` - Settings loaded in ${loadTime}ms`);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - API Server from settings: ${settings.apiServer || "Not Set"}`,
|
||||||
|
);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Partner API Server from settings: ${settings.partnerApiServer || "Not Set"}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test 3: Database query
|
||||||
|
this.addUrlTestResult(`\n💾 Testing Database Query:`);
|
||||||
|
const dbStartTime = Date.now();
|
||||||
|
const dbResult = await this.$dbQuery(
|
||||||
|
"SELECT apiServer, partnerApiServer, activeDid FROM settings WHERE id = ? OR accountDid = ?",
|
||||||
|
[1, this.activeDid || ""],
|
||||||
|
);
|
||||||
|
const dbTime = Date.now() - dbStartTime;
|
||||||
|
|
||||||
|
if (dbResult?.values) {
|
||||||
|
this.addUrlTestResult(` - Database query completed in ${dbTime}ms`);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Raw DB values: ${JSON.stringify(dbResult.values)}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Database query failed or returned no results`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 4: Environment variables
|
||||||
|
this.addUrlTestResult(`\n🌍 Testing Environment Variables:`);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - VITE_PLATFORM: ${import.meta.env.VITE_PLATFORM || "Not Set"}`,
|
||||||
|
);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - VITE_DEFAULT_ENDORSER_API_SERVER: ${import.meta.env.VITE_DEFAULT_ENDORSER_API_SERVER || "Not Set"}`,
|
||||||
|
);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - VITE_DEFAULT_PARTNER_API_SERVER: ${import.meta.env.VITE_DEFAULT_PARTNER_API_SERVER || "Not Set"}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test 5: Constants
|
||||||
|
this.addUrlTestResult(`\n📋 Testing App Constants:`);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - PROD_ENDORSER_API_SERVER: ${AppString.PROD_ENDORSER_API_SERVER}`,
|
||||||
|
);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - PROD_PARTNER_API_SERVER: ${AppString.PROD_PARTNER_API_SERVER}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test 6: Change detection
|
||||||
|
this.addUrlTestResult(`\n🔄 Testing Change Detection:`);
|
||||||
|
const originalApiServer = this.apiServer;
|
||||||
|
const originalPartnerServer = this.partnerApiServer;
|
||||||
|
|
||||||
|
// Simulate a change
|
||||||
|
this.addUrlTestResult(` - Original API Server: ${originalApiServer}`);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Original Partner Server: ${originalPartnerServer}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test 7: Settings update
|
||||||
|
this.addUrlTestResult(`\n💾 Testing Settings Update:`);
|
||||||
|
const testChanges = {
|
||||||
|
apiServer:
|
||||||
|
originalApiServer === "https://api.endorser.ch"
|
||||||
|
? "https://test-api.endorser.ch"
|
||||||
|
: "https://api.endorser.ch",
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Attempting to change API Server to: ${testChanges.apiServer}`,
|
||||||
|
);
|
||||||
|
const updateResult = await this.$saveSettings(testChanges);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Update result: ${updateResult ? "Success" : "Failed"}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test 8: Verify change propagation
|
||||||
|
this.addUrlTestResult(`\n✅ Testing Change Propagation:`);
|
||||||
|
const newSettings = await this.$accountSettings();
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - New API Server from settings: ${newSettings.apiServer || "Not Set"}`,
|
||||||
|
);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Component state API Server: ${this.apiServer || "Not Set"}`,
|
||||||
|
);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Change propagated: ${newSettings.apiServer === this.apiServer ? "Yes" : "No"}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test 9: Revert changes
|
||||||
|
this.addUrlTestResult(`\n🔄 Reverting Changes:`);
|
||||||
|
const revertResult = await this.$saveSettings({
|
||||||
|
apiServer: originalApiServer,
|
||||||
|
});
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Revert result: ${revertResult ? "Success" : "Failed"}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test 10: Final verification
|
||||||
|
this.addUrlTestResult(`\n🎯 Final Verification:`);
|
||||||
|
const finalSettings = await this.$accountSettings();
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Final API Server: ${finalSettings.apiServer || "Not Set"}`,
|
||||||
|
);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
` - Matches original: ${finalSettings.apiServer === originalApiServer ? "Yes" : "No"}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.addUrlTestResult(`\n✅ URL flow test completed successfully!`);
|
||||||
|
logger.info("[TestView] ✅ URL flow test completed successfully");
|
||||||
|
} catch (error) {
|
||||||
|
const errorMsg = `❌ URL flow test failed: ${error instanceof Error ? error.message : String(error)}`;
|
||||||
|
this.addUrlTestResult(errorMsg);
|
||||||
|
logger.error("[TestView] ❌ URL flow test failed:", error);
|
||||||
|
} finally {
|
||||||
|
this.isUrlTestRunning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a result to the URL test results array.
|
||||||
|
*/
|
||||||
|
private addUrlTestResult(message: string) {
|
||||||
|
this.urlTestResults.push(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the API server to the production URL.
|
||||||
|
*/
|
||||||
|
public changeApiServer() {
|
||||||
|
const currentServer = this.apiServer;
|
||||||
|
const newServer =
|
||||||
|
currentServer === "https://api.endorser.ch"
|
||||||
|
? "https://test-api.endorser.ch"
|
||||||
|
: "https://api.endorser.ch";
|
||||||
|
|
||||||
|
logger.info("[TestView] 🔄 Changing API server:", {
|
||||||
|
from: currentServer,
|
||||||
|
to: newServer,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.apiServer = newServer;
|
||||||
|
this.addUrlTestResult(
|
||||||
|
`API Server changed from ${currentServer} to ${newServer}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the partner API server to the production URL.
|
||||||
|
*/
|
||||||
|
public changePartnerApiServer() {
|
||||||
|
const currentServer = this.partnerApiServer;
|
||||||
|
const newServer =
|
||||||
|
currentServer === "https://partner-api.endorser.ch"
|
||||||
|
? "https://test-partner-api.endorser.ch"
|
||||||
|
: "https://partner-api.endorser.ch";
|
||||||
|
|
||||||
|
logger.info("[TestView] 🔄 Changing partner API server:", {
|
||||||
|
from: currentServer,
|
||||||
|
to: newServer,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.partnerApiServer = newServer;
|
||||||
|
this.addUrlTestResult(
|
||||||
|
`Partner API Server changed from ${currentServer} to ${newServer}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets all URL-related settings to their initial values.
|
||||||
|
*/
|
||||||
|
public resetToDefaults() {
|
||||||
|
this.apiServer = AppString.TEST_ENDORSER_API_SERVER;
|
||||||
|
this.partnerApiServer = AppString.TEST_PARTNER_API_SERVER;
|
||||||
|
this.activeDid = "";
|
||||||
|
this.addUrlTestResult("URL Flow Test Results Reset to Defaults.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refreshes settings from the database to verify changes.
|
||||||
|
*/
|
||||||
|
public async refreshSettings() {
|
||||||
|
try {
|
||||||
|
logger.info("[TestView] 🔄 Refreshing settings from database");
|
||||||
|
const settings = await this.$accountSettings();
|
||||||
|
|
||||||
|
// Update component state
|
||||||
|
this.apiServer = settings.apiServer || "";
|
||||||
|
this.partnerApiServer = settings.partnerApiServer || "";
|
||||||
|
|
||||||
|
logger.info("[TestView] ✅ Settings refreshed:", {
|
||||||
|
apiServer: this.apiServer,
|
||||||
|
partnerApiServer: this.partnerApiServer,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addUrlTestResult(
|
||||||
|
`Settings refreshed - API Server: ${this.apiServer}, Partner API Server: ${this.partnerApiServer}`,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error("[TestView] ❌ Error refreshing settings:", error);
|
||||||
|
this.addUrlTestResult(
|
||||||
|
`Error refreshing settings: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the current environment state to the console.
|
||||||
|
*/
|
||||||
|
public logEnvironmentState() {
|
||||||
|
logger.info("[TestView] 🌐 Current Environment State:", {
|
||||||
|
VITE_PLATFORM: import.meta.env.VITE_PLATFORM,
|
||||||
|
VITE_DEFAULT_ENDORSER_API_SERVER: import.meta.env
|
||||||
|
.VITE_DEFAULT_ENDORSER_API_SERVER,
|
||||||
|
VITE_DEFAULT_PARTNER_API_SERVER: import.meta.env
|
||||||
|
.VITE_DEFAULT_PARTNER_API_SERVER,
|
||||||
|
NODE_ENV: process.env.NODE_ENV,
|
||||||
|
activeDid: this.activeDid,
|
||||||
|
apiServer: this.apiServer,
|
||||||
|
partnerApiServer: this.partnerApiServer,
|
||||||
|
});
|
||||||
|
this.$notify({
|
||||||
|
group: "info",
|
||||||
|
type: "info",
|
||||||
|
title: "Environment State Logged",
|
||||||
|
text: "Current environment state logged to console.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current platform based on the API server.
|
||||||
|
*/
|
||||||
|
public getCurrentPlatform(): string {
|
||||||
|
if (this.apiServer?.includes(AppString.PROD_ENDORSER_API_SERVER)) {
|
||||||
|
return "Production";
|
||||||
|
} else if (this.apiServer?.includes(AppString.TEST_ENDORSER_API_SERVER)) {
|
||||||
|
return "Test";
|
||||||
|
} else {
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user