Browse Source

fix: Fix onboard-meeting-members deep link with groupId.

fix-deep-link
Trent Larson 3 days ago
parent
commit
016e849d3e
  1. 1
      package.json
  2. 28
      src/interfaces/deepLinks.ts
  3. 28
      src/services/deepLinks.ts
  4. 4
      src/views/DeepLinkErrorView.vue
  5. 2
      src/views/OnboardMeetingMembersView.vue

1
package.json

@ -12,6 +12,7 @@
"type-check": "tsc --noEmit",
"prebuild": "eslint --ext .js,.ts,.vue --ignore-path .gitignore src && node sw_combine.js && node scripts/copy-wasm.js",
"test:prerequisites": "node scripts/check-prerequisites.js",
"test:all": "npm run lint && tsc && npm run test:web && npm run test:mobile && ./scripts/test-safety-check.sh && echo '\n\n\nGotta add the performance tests'",
"test:web": "npx playwright test -c playwright.config-local.ts --trace on",
"test:mobile": "./scripts/test-mobile.sh",
"test:android": "node scripts/test-android.js",

28
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;

28
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 type { DeepLinkError } from "../interfaces/deepLinks";
import { logger } from "../utils/logger";
@ -74,7 +75,7 @@ function getFirstKeyFromZodObject(
* because "router.replace" expects the right parameter name for the route.
*/
export const ROUTE_MAP: Record<string, { name: string; paramKey?: string }> =
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<any>);
@ -198,15 +199,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<string, string> = {};
let validatedQueryParams: Record<string, string> = {};
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
logger.error(
`[DeepLink] Invalid parameters for route name ${routeName} for path: ${path}: ${JSON.stringify(error)} ... with params: ${JSON.stringify(params)} ... and query: ${JSON.stringify(query)}`,
`[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",
@ -226,20 +234,22 @@ export class DeepLinkHandler {
try {
await this.router.replace({
name: routeName,
params: validatedParams,
params: validatedPathParams,
query: validatedQueryParams
});
} catch (error) {
logger.error(
`[DeepLink] Error routing to route name ${routeName} for path: ${path}: ${JSON.stringify(error)} ... with validated params: ${JSON.stringify(validatedParams)}`,
`[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,
},
});
}

4
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];
}),

2
src/views/OnboardMeetingMembersView.vue

@ -113,7 +113,7 @@ export default class OnboardMeetingMembersView extends Vue {
try {
// Identity creation should be handled by router guard, but keep as fallback for meeting setup
if (!this.activeDid) {
logger.info(
this.$logAndConsole(
"[OnboardMeetingMembersView] No active DID found, creating identity as fallback for meeting setup",
);
this.activeDid = await generateSaveAndActivateIdentity();

Loading…
Cancel
Save