diff --git a/BUILDING.md b/BUILDING.md index c2ce41f9..1cc9d74d 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -364,7 +364,7 @@ Prerequisites: macOS with Xcode installed 4. Bump the version to match Android & package.json: ``` - cd ios/App && xcrun agvtool new-version 39 && perl -p -i -e "s/MARKETING_VERSION = .*;/MARKETING_VERSION = 1.0.6;/g" App.xcodeproj/project.pbxproj && cd - + cd ios/App && xcrun agvtool new-version 43 && perl -p -i -e "s/MARKETING_VERSION = .*;/MARKETING_VERSION = 1.0.9;/g" App.xcodeproj/project.pbxproj && cd - # Unfortunately this edits Info.plist directly. #xcrun agvtool new-marketing-version 0.4.5 ``` diff --git a/android/app/build.gradle b/android/app/build.gradle index c9d30d0e..12f9691f 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -31,8 +31,8 @@ android { applicationId "app.timesafari.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 39 - versionName "1.0.6" + versionCode 43 + versionName "1.0.9" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj index 381f4bab..25f23871 100644 --- a/ios/App/App.xcodeproj/project.pbxproj +++ b/ios/App/App.xcodeproj/project.pbxproj @@ -403,7 +403,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 39; + CURRENT_PROJECT_VERSION = 43; DEVELOPMENT_TEAM = GM3FS5JQPH; ENABLE_APP_SANDBOX = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -413,7 +413,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.6; + MARKETING_VERSION = 1.0.9; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = app.timesafari; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -430,7 +430,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 39; + CURRENT_PROJECT_VERSION = 43; DEVELOPMENT_TEAM = GM3FS5JQPH; ENABLE_APP_SANDBOX = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -440,7 +440,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.6; + MARKETING_VERSION = 1.0.9; PRODUCT_BUNDLE_IDENTIFIER = app.timesafari; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; diff --git a/package-lock.json b/package-lock.json index 94fef062..abc6e934 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "timesafari", - "version": "1.0.6", + "version": "1.0.10-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "timesafari", - "version": "1.0.6", + "version": "1.0.10-beta", "dependencies": { "@capacitor-community/sqlite": "6.0.2", "@capacitor-mlkit/barcode-scanning": "^6.0.0", diff --git a/package.json b/package.json index d9ce17ec..afd3c178 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "timesafari", - "version": "1.0.6", + "version": "1.0.10-beta", "description": "Time Safari Application", "author": { "name": "Time Safari Team" diff --git a/src/interfaces/deepLinks.ts b/src/interfaces/deepLinks.ts index d5266c7a..0fe5c68d 100644 --- a/src/interfaces/deepLinks.ts +++ b/src/interfaces/deepLinks.ts @@ -28,7 +28,7 @@ import { z } from "zod"; // Parameter validation schemas for each route type -export const deepLinkSchemas = { +export const deepLinkPathSchemas = { claim: z.object({ id: z.string(), }), @@ -60,7 +60,7 @@ export const deepLinkSchemas = { jwt: z.string().optional(), }), "onboard-meeting-members": z.object({ - id: z.string(), + groupId: z.string(), }), project: z.object({ id: z.string(), @@ -70,6 +70,17 @@ export const deepLinkSchemas = { }), }; +export const deepLinkQuerySchemas = { + "onboard-meeting-members": z.object({ + password: z.string(), + }), +}; + +// Add a union type of all valid route paths +export const VALID_DEEP_LINK_ROUTES = Object.keys( + deepLinkPathSchemas, +) as readonly (keyof typeof deepLinkPathSchemas)[]; + // Create a type from the array export type DeepLinkRoute = (typeof VALID_DEEP_LINK_ROUTES)[number]; @@ -80,14 +91,13 @@ export const baseUrlSchema = z.object({ queryParams: z.record(z.string()).optional(), }); -// Add a union type of all valid route paths -export const VALID_DEEP_LINK_ROUTES = Object.keys( - deepLinkSchemas, -) as readonly (keyof typeof deepLinkSchemas)[]; +// export type DeepLinkPathParams = { +// [K in keyof typeof deepLinkPathSchemas]: z.infer<(typeof deepLinkPathSchemas)[K]>; +// }; -export type DeepLinkParams = { - [K in keyof typeof deepLinkSchemas]: z.infer<(typeof deepLinkSchemas)[K]>; -}; +// export type DeepLinkQueryParams = { +// [K in keyof typeof deepLinkQuerySchemas]: z.infer<(typeof deepLinkQuerySchemas)[K]>; +// }; export interface DeepLinkError extends Error { code: string; diff --git a/src/services/deepLinks.ts b/src/services/deepLinks.ts index f3e10fed..e2ef7046 100644 --- a/src/services/deepLinks.ts +++ b/src/services/deepLinks.ts @@ -47,10 +47,11 @@ import { Router } from "vue-router"; import { z } from "zod"; import { - deepLinkSchemas, + deepLinkPathSchemas, baseUrlSchema, routeSchema, DeepLinkRoute, + deepLinkQuerySchemas, } from "../interfaces/deepLinks"; import { logConsoleAndDb } from "../db/databaseUtil"; import type { DeepLinkError } from "../interfaces/deepLinks"; @@ -74,7 +75,7 @@ function getFirstKeyFromZodObject( * because "router.replace" expects the right parameter name for the route. */ export const ROUTE_MAP: Record = - Object.entries(deepLinkSchemas).reduce( + Object.entries(deepLinkPathSchemas).reduce( (acc, [routeName, schema]) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const paramKey = getFirstKeyFromZodObject(schema as z.ZodObject); @@ -199,16 +200,22 @@ export class DeepLinkHandler { } // Continue with parameter validation as before... - const schema = deepLinkSchemas[path as keyof typeof deepLinkSchemas]; + const pathSchema = deepLinkPathSchemas[path as keyof typeof deepLinkPathSchemas]; + const querySchema = deepLinkQuerySchemas[path as keyof typeof deepLinkQuerySchemas]; - let validatedParams; + let validatedPathParams: Record = {}; + let validatedQueryParams: Record = {}; try { - validatedParams = await schema.parseAsync(params); + if (pathSchema) { + validatedPathParams = await pathSchema.parseAsync(params); + } + if (querySchema) { + validatedQueryParams = await querySchema.parseAsync(query); + } } catch (error) { // For parameter validation errors, provide specific error feedback logConsoleAndDb( - `[DeepLink] Invalid parameters for route name ${routeName} for path: ${path}: ${JSON.stringify(error)} ... with params: ${JSON.stringify(params)} ... and query: ${JSON.stringify(query)}`, - true, + `[DeepLink] Invalid parameters for route name ${routeName} for path: ${path} ... with error: ${JSON.stringify(error)} ... with params: ${JSON.stringify(params)} ... and query: ${JSON.stringify(query)}`, ); await this.router.replace({ name: "deep-link-error", @@ -228,21 +235,22 @@ export class DeepLinkHandler { try { await this.router.replace({ name: routeName, - params: validatedParams, + params: validatedPathParams, + query: validatedQueryParams }); } catch (error) { logConsoleAndDb( - `[DeepLink] Error routing to route name ${routeName} for path: ${path}: ${JSON.stringify(error)} ... with validated params: ${JSON.stringify(validatedParams)}`, - true, + `[DeepLink] Error routing to route name ${routeName} for path: ${path}: ${JSON.stringify(error)} ... with validated params: ${JSON.stringify(validatedPathParams)} ... and query: ${JSON.stringify(validatedQueryParams)}`, ); // For parameter validation errors, provide specific error feedback await this.router.replace({ name: "deep-link-error", - params: validatedParams, + params: validatedPathParams, query: { originalPath: path, errorCode: "ROUTING_ERROR", errorMessage: `Error routing to ${routeName}: ${JSON.stringify(error)}`, + ...validatedQueryParams, }, }); } diff --git a/src/views/DeepLinkErrorView.vue b/src/views/DeepLinkErrorView.vue index 6decd859..a3b53b09 100644 --- a/src/views/DeepLinkErrorView.vue +++ b/src/views/DeepLinkErrorView.vue @@ -47,7 +47,7 @@ import { computed, onMounted } from "vue"; import { useRoute, useRouter } from "vue-router"; import { VALID_DEEP_LINK_ROUTES, - deepLinkSchemas, + deepLinkPathSchemas, } from "../interfaces/deepLinks"; import { logConsoleAndDb } from "../db/databaseUtil"; import { logger } from "../utils/logger"; @@ -56,7 +56,7 @@ const route = useRoute(); const router = useRouter(); // an object with the route as the key and the first param name as the value const deepLinkSchemaKeys = Object.fromEntries( - Object.entries(deepLinkSchemas).map(([route, schema]) => { + Object.entries(deepLinkPathSchemas).map(([route, schema]) => { const param = Object.keys(schema.shape)[0]; return [route, param]; }), diff --git a/src/views/OnboardMeetingMembersView.vue b/src/views/OnboardMeetingMembersView.vue index 20cdbcac..a501569e 100644 --- a/src/views/OnboardMeetingMembersView.vue +++ b/src/views/OnboardMeetingMembersView.vue @@ -117,6 +117,9 @@ export default class OnboardMeetingMembersView extends Vue { this.isRegistered = settings.isRegistered || false; try { if (!this.activeDid) { + logConsoleAndDb( + "[OnboardMeetingMembersView] No active DID found, creating identity as fallback for meeting setup", + ); this.activeDid = await generateSaveAndActivateIdentity(); this.isRegistered = false; }