chore: commit to move to laptop

This commit is contained in:
Matthew Raymer
2025-10-31 09:56:23 +00:00
parent c1cc8802f6
commit 01b7dae5df
26 changed files with 2243 additions and 145 deletions

View File

@@ -213,8 +213,61 @@ export const MOCK_STARRED_PROJECTS_RESPONSE = {
} as const;
/**
* Generate test JWT token for User Zero
* Mimics the crowd-master createEndorserJwtForDid function
* Generate ES256K signed JWT token for User Zero using DID-based signing
*
* This function mimics TimeSafari's createEndorserJwtForKey() function,
* using did-jwt library with ES256K algorithm (DID-based signing).
*
* @returns Promise<string> ES256K signed JWT token
*/
export async function generateEndorserJWT(): Promise<string> {
try {
// Dynamic import to avoid loading did-jwt in environments where it's not needed
const { createJWT, SimpleSigner } = await import('did-jwt');
const { HDNodeWallet, Mnemonic } = await import('ethers');
// Derive Ethereum private key from seed phrase
// Using the same derivation as TimeSafari (m/44'/60'/0'/0/0 - Ethereum standard)
const mnemonic = Mnemonic.fromPhrase(TEST_USER_ZERO_CONFIG.identity.seedPhrase);
const wallet = HDNodeWallet.fromMnemonic(mnemonic);
const privateKeyHex = wallet.privateKey.slice(2); // Remove '0x' prefix
// Create signer for ES256K (Ethereum secp256k1 curve)
const signer = SimpleSigner(privateKeyHex);
// Create JWT payload with standard claims
const nowEpoch = Math.floor(Date.now() / 1000);
const expiresIn = TEST_USER_ZERO_CONFIG.api.jwtExpirationMinutes * 60;
const payload = {
// Standard JWT claims
iat: nowEpoch,
exp: nowEpoch + expiresIn,
iss: TEST_USER_ZERO_CONFIG.identity.did,
sub: TEST_USER_ZERO_CONFIG.identity.did,
// Additional claims that endorser-ch might expect
aud: "endorser-ch"
};
// Create ES256K signed JWT (ES256K is the default algorithm for did-jwt)
const jwt = await createJWT(payload, {
issuer: TEST_USER_ZERO_CONFIG.identity.did,
signer: signer,
expiresIn: expiresIn
});
return jwt;
} catch (error) {
console.error('Failed to generate ES256K JWT:', error);
throw new Error(`JWT generation failed: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Generate test JWT token for User Zero (DEPRECATED - use generateEndorserJWT instead)
*
* @deprecated This function generates an unsigned test token. Use generateEndorserJWT()
* for real ES256K signed tokens that work with the endorser-ch API.
*/
export function generateTestJWT(): string {
const nowEpoch = Math.floor(Date.now() / 1000);
@@ -260,7 +313,7 @@ export class TestUserZeroAPI {
*/
setBaseUrl(url: string): void {
this.baseUrl = url;
// eslint-disable-next-line no-console
console.log("🔧 API base URL updated to:", url);
}
@@ -278,7 +331,7 @@ export class TestUserZeroAPI {
if (useMock) {
// Return mock data for offline testing
// eslint-disable-next-line no-console
console.log("🧪 Using mock starred projects response");
return MOCK_STARRED_PROJECTS_RESPONSE;
}
@@ -297,9 +350,9 @@ export class TestUserZeroAPI {
afterId: afterId || TEST_USER_ZERO_CONFIG.starredProjects.lastAckedJwtId
};
// eslint-disable-next-line no-console
console.log("🌐 Making real API call to:", url);
// eslint-disable-next-line no-console
console.log("📦 Request body:", requestBody);
const response = await fetch(url, {
@@ -320,7 +373,7 @@ export class TestUserZeroAPI {
*/
refreshToken(): void {
this.jwt = generateTestJWT();
// eslint-disable-next-line no-console
console.log("🔄 JWT token refreshed");
}

View File

@@ -105,7 +105,7 @@ router.beforeEach((to, from, next) => {
}
// Add loading state
// eslint-disable-next-line no-console
console.log(`🔄 Navigating from ${String(from.name) || 'unknown'} to ${String(to.name) || 'unknown'}`)
next()
@@ -113,7 +113,7 @@ router.beforeEach((to, from, next) => {
router.afterEach((to) => {
// Clear any previous errors on successful navigation
// eslint-disable-next-line no-console
console.log(`✅ Navigation completed: ${String(to.name) || 'unknown'}`)
})

View File

@@ -115,6 +115,7 @@ import { useRouter } from 'vue-router'
import { useAppStore } from '@/stores/app'
import ActionCard from '@/components/cards/ActionCard.vue'
import StatusCard from '@/components/cards/StatusCard.vue'
import { TEST_USER_ZERO_CONFIG, generateEndorserJWT } from '@/config/test-user-zero'
const router = useRouter()
const appStore = useAppStore()
@@ -429,9 +430,54 @@ const openConsole = (): void => {
alert('📖 Console Logs\n\nOpen your browser\'s Developer Tools (F12) and check the Console tab for detailed diagnostic information.')
}
// Configure native fetcher with test user zero credentials
const configureNativeFetcher = async (): Promise<void> => {
try {
const { Capacitor } = await import('@capacitor/core')
const isNative = Capacitor.isNativePlatform()
if (isNative) {
const { DailyNotification } = await import('@timesafari/daily-notification-plugin')
// Get API server URL based on mode and platform
const apiBaseUrl = TEST_USER_ZERO_CONFIG.getApiServerUrl()
// Only configure if not in mock mode
if (TEST_USER_ZERO_CONFIG.api.serverMode !== 'mock' && apiBaseUrl !== 'mock://localhost') {
console.log('🔧 Configuring native fetcher with:', {
apiBaseUrl,
activeDid: TEST_USER_ZERO_CONFIG.identity.did.substring(0, 30) + '...',
serverMode: TEST_USER_ZERO_CONFIG.api.serverMode
})
// Generate ES256K JWT token using did-jwt library
// This mimics TimeSafari's createEndorserJwtForKey() function
// In production TimeSafari app, this would use:
// const account = await retrieveFullyDecryptedAccount(activeDid);
// const jwtToken = await createEndorserJwtForKey(account, {...});
const jwtToken = await generateEndorserJWT()
await DailyNotification.configureNativeFetcher({
apiBaseUrl: apiBaseUrl,
activeDid: TEST_USER_ZERO_CONFIG.identity.did,
jwtToken: jwtToken // Pre-generated token (ES256K signed in production)
})
console.log('✅ Native fetcher configured successfully')
} else {
console.log('⏭️ Skipping native fetcher configuration (mock mode enabled)')
}
}
} catch (error) {
console.error('❌ Failed to configure native fetcher:', error)
// Don't block app initialization if configuration fails
}
}
// Initialize system status when component mounts
onMounted(async () => {
console.log('🏠 HomeView mounted - checking initial system status...')
await configureNativeFetcher()
await checkSystemStatus()
})
</script>

View File

@@ -19,7 +19,7 @@
</div>
<div class="config-item">
<label>API Server:</label>
<span class="config-value">{{ config.api.server }}</span>
<span class="config-value">{{ config.getApiServerUrl() }} (mode: {{ config.api.serverMode }})</span>
</div>
<div class="config-item">
<label>JWT Expiration:</label>