-
Notifications
You must be signed in to change notification settings - Fork 2
Feat/evault provisioning via phone #188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Caution Review failedThe pull request is closed. WalkthroughThis update introduces a comprehensive identity verification and vault provisioning flow, spanning both the frontend (eid-wallet) and backend (evault-provisioner, registry). It adds new verification steps, dynamic user and document data handling, backend API integration, TypeORM-based persistence, event-driven status updates, and utility enhancements. Several new modules, entities, controllers, and configuration improvements are included. Changes
Sequence Diagram(s)End-to-End Verification and Vault Provisioning FlowsequenceDiagram
participant User as User (Frontend)
participant EidWallet as eid-wallet (Svelte)
participant Provisioner as evault-provisioner (Backend)
participant Veriff as Veriff API
participant Registry as Registry Service
User->>EidWallet: Start verification
EidWallet->>Provisioner: POST /verification (create session)
Provisioner->>Veriff: Create session via API
Veriff-->>Provisioner: Session ID
Provisioner-->>EidWallet: Session ID
User->>EidWallet: Capture passport & selfie
EidWallet->>Provisioner: POST /verification/:id/media (upload images)
Provisioner->>Veriff: Forward images
Veriff-->>Provisioner: Webhook (verification decision)
Provisioner->>EidWallet: SSE status updates
EidWallet->>Provisioner: POST /provision (with verificationId)
Provisioner->>Registry: POST /register (register vault)
Registry-->>Provisioner: Vault info
Provisioner-->>EidWallet: Vault details
EidWallet->>User: Display vault & onboarding complete
Possibly related PRs
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 33
🔭 Outside diff range comments (1)
infrastructure/evault-provisioner/src/index.ts (1)
141-149
: 🛠️ Refactor suggestionImprove error handling specificity
The current error handling loses the original error message when it's not an Axios error.
} catch (error) { - const axiosError = error as AxiosError; - res.status(500).json({ - success: false, - error: axiosError.response?.data || axiosError.message, - message: "Failed to provision evault instance", - }); + if (error instanceof AxiosError) { + res.status(500).json({ + success: false, + error: error.response?.data || error.message, + message: "Failed to provision evault instance", + }); + } else { + res.status(500).json({ + success: false, + error: error instanceof Error ? error.message : String(error), + message: "Failed to provision evault instance", + }); + } }
🧹 Nitpick comments (24)
infrastructure/evault-provisioner/src/utils/hmac.ts (1)
1-1
: Use node: protocol for Node.js imports.Following Node.js best practices, builtin modules should be imported with the node: protocol for better clarity and explicit indication of Node.js modules.
-import { createHmac } from "crypto"; +import { createHmac } from "node:crypto";🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: A Node.js builtin module should be imported with the node: protocol.
Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.(lint/style/useNodejsImportProtocol)
infrastructure/evault-provisioner/src/utils/eventEmitter.ts (1)
1-1
: Use the node: protocol for Node.js builtin imports.The import should use the
node:
protocol to be more explicit about importing a Node.js builtin module, following modern best practices.-import { EventEmitter } from "events" +import { EventEmitter } from "node:events"🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: A Node.js builtin module should be imported with the node: protocol.
Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.(lint/style/useNodejsImportProtocol)
infrastructure/evault-provisioner/src/migrations/1748966722767-migration.ts (1)
1-1
: Optimize imports for better tree-shaking.Use
import type
for type-only imports to ensure they are removed by the compiler and avoid loading unnecessary modules.-import { MigrationInterface, QueryRunner } from "typeorm"; +import type { MigrationInterface, QueryRunner } from "typeorm";🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
infrastructure/evault-provisioner/src/migrations/1748968097591-migration.ts (1)
1-1
: Optimize imports by usingimport type
for TypeORM interfaces.The static analysis tool correctly identifies that these imports are only used as types. Using
import type
ensures they're removed during compilation and avoids loading unnecessary modules.-import { MigrationInterface, QueryRunner } from "typeorm"; +import type { MigrationInterface, QueryRunner } from "typeorm";🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
infrastructure/eid-wallet/src/routes/(app)/ePassport/+page.svelte (2)
11-13
: Remove unused shareEPassport function.The
shareEPassport
function is no longer used since the share button was removed from the UI. Consider removing it to keep the code clean.- function shareEPassport() { - alert("EPassport Code shared!"); - }
21-21
: Consider removing debug console.log.The
console.log(userData)
appears to be for debugging purposes and should be removed in production code.- console.log(userData);
infrastructure/evault-provisioner/src/migrations/1748932757644-migration.ts (1)
1-1
: Optimize imports by usingimport type
for TypeORM interfaces.Same as the other migration file - these imports are only used as types and should use
import type
.-import { MigrationInterface, QueryRunner } from "typeorm"; +import type { MigrationInterface, QueryRunner } from "typeorm";🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte (2)
18-22
: LGTM! Consider adding confirmation dialog for wallet reset.The
nukeWallet
function correctly clears user data and security PIN before navigating to onboarding. This provides a clean reset mechanism for the wallet.Consider adding a confirmation dialog before executing the wallet reset to prevent accidental data loss.
57-57
: Replace placeholder text with meaningful label.The ButtonAction component contains placeholder text "asdfasdf" which should be replaced with a descriptive label for the wallet reset functionality.
- <ButtonAction callback={nukeWallet}>asdfasdf</ButtonAction> + <ButtonAction callback={nukeWallet}>Reset Wallet</ButtonAction>infrastructure/evault-provisioner/src/config/database.ts (1)
4-4
: Use Node.js import protocol for built-in modules.Following the static analysis hint, use the
node:
protocol for Node.js built-in modules for better clarity and explicit indication.-import { join } from "path" +import { join } from "node:path"🧰 Tools
🪛 Biome (1.9.4)
[error] 4-4: A Node.js builtin module should be imported with the node: protocol.
Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.(lint/style/useNodejsImportProtocol)
infrastructure/eid-wallet/src/lib/global/controllers/evault.ts (1)
17-17
: Consider more descriptive variable name.The variable name
resolvedUser
in the promise resolution should beresolvedVault
to match the context.- .then((resolvedUser) => { - this.#store.set("vault", resolvedUser); + .then((resolvedVault) => { + this.#store.set("vault", resolvedVault);🧰 Tools
🪛 Biome (1.9.4)
[error] 17-17: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found '.'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 17-17: Expected a parameter but instead found '('.
Expected a parameter here.
(parse)
[error] 17-17: expected
,
but instead foundresolvedUser
Remove resolvedUser
(parse)
[error] 17-17: Expected a class method body but instead found '=>'.
Expected a class method body here.
(parse)
[error] 17-17: Do not add then to a class.
(lint/suspicious/noThenProperty)
infrastructure/eid-wallet/src/lib/fragments/IdentityCard/IdentityCard.svelte (1)
44-44
: Break down the long CSS class string for better readability.This single line contains a complex conditional expression that's difficult to read and maintain. Consider extracting this logic into a computed property or breaking it into multiple lines.
- const baseClasses = `relative ${variant === "eName" ? "bg-black-900" : variant === "ePassport" ? "bg-primary" : "bg-gray"} rounded-3xl w-full min-h-[150px] text-white overflow-hidden`; + const getBackgroundClass = (variant: string) => { + switch (variant) { + case "eName": return "bg-black-900"; + case "ePassport": return "bg-primary"; + default: return "bg-gray"; + } + }; + + const baseClasses = `relative ${getBackgroundClass(variant)} rounded-3xl w-full min-h-[150px] text-white overflow-hidden`;platforms/registry/src/index.ts (1)
38-47
: Improve authorization header validation.The authorization header validation could be more robust and provide clearer error messages.
const checkSharedSecret = async (request: any, reply: any) => { const authHeader = request.headers.authorization; - if (!authHeader || !authHeader.startsWith("Bearer ")) { + if (!authHeader) { + return reply + .status(401) + .send({ error: "Authorization header is required" }); + } + + if (!authHeader.startsWith("Bearer ")) { return reply .status(401) - .send({ error: "Missing or invalid authorization header" }); + .send({ error: "Authorization header must use Bearer token format" }); }infrastructure/eid-wallet/src/routes/(auth)/verify/steps/passport.svelte (1)
52-52
: Remove debug console.log statements.Debug console.log statements should be removed from production code.
- console.log("huh?"); const context1 = canvas1.getContext("2d"); // ... - console.log("here???");Also applies to: 72-72
infrastructure/evault-provisioner/src/entities/Verification.ts (1)
20-21
: Consider more specific typing for the data field.The
Record<string, unknown>
type is quite loose. Consider defining a more specific interface for the expected data structure.+interface VerificationData { + // Define specific fields based on your verification data structure + [key: string]: unknown; +} - @Column({ type: "jsonb", nullable: true }) - data!: Record<string, unknown>; + @Column({ type: "jsonb", nullable: true }) + data?: VerificationData | null;infrastructure/evault-provisioner/src/services/VerificationService.ts (2)
1-2
: Use import type for type-only imports.Following the static analysis hint, imports that are only used as types should use
import type
to ensure they're removed during compilation.-import { DeepPartial, Repository } from "typeorm"; -import { Verification } from "../entities/Verification"; +import type { DeepPartial, Repository } from "typeorm"; +import type { Verification } from "../entities/Verification";🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
[error] 2-2: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
9-12
: Consider adding input validation.The create method should validate input data to ensure data integrity and provide better error messages.
async create(data: Partial<Verification>): Promise<Verification> { + if (!data || Object.keys(data).length === 0) { + throw new Error("Verification data cannot be empty"); + } + const verification = this.verificationRepository.create(data); return await this.verificationRepository.save(verification); }infrastructure/evault-provisioner/src/index.ts (3)
8-8
: Use Node.js protocol for builtin module importFor better clarity and consistency with modern Node.js practices.
-import path from "path"; +import path from "node:path";🧰 Tools
🪛 Biome (1.9.4)
[error] 8-8: A Node.js builtin module should be imported with the node: protocol.
Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.(lint/style/useNodejsImportProtocol)
9-9
: Remove unused importThe
createHmacSignature
import is not used in this file.-import { createHmacSignature } from "./utils/hmac";
99-103
: Simplify URL constructionThe template literal is not needed here as noted by static analysis.
- new URL( - `/.well-known/jwks.json`, - process.env.PUBLIC_REGISTRY_URL, - ).toString(), + new URL( + "/.well-known/jwks.json", + process.env.PUBLIC_REGISTRY_URL, + ).toString(),🧰 Tools
🪛 Biome (1.9.4)
[error] 100-100: Do not use template literals if interpolation and special-character handling are not needed.
Unsafe fix: Replace with string literal
(lint/style/noUnusedTemplateLiteral)
infrastructure/eid-wallet/src/lib/global/controllers/user.ts (1)
57-72
: Consider extracting common promise handling logicBoth
user
anddocument
setters have identical promise handling logic. Consider extracting this to reduce duplication.private async handleAsyncSetter<T>( key: string, value: Promise<T | undefined> | T | undefined ): Promise<void> { if (value instanceof Promise) { try { const resolved = await value; await this.#store.set(key, resolved); } catch (error) { console.error(`Failed to set ${key}:`, error); } } else { await this.#store.set(key, value); } } set user(user: Promise<Record<string, string> | undefined> | Record<string, string> | undefined) { this.handleAsyncSetter("user", user); } set document(document: Promise<Record<string, string> | undefined> | Record<string, string> | undefined) { this.handleAsyncSetter("doc", document); }Also applies to: 89-106
🧰 Tools
🪛 Biome (1.9.4)
[error] 61-61: expected
)
but instead found,
Remove ,
(parse)
[error] 63-63: expected a semicolon to end the class property, but found none
(parse)
[error] 63-63: expected a semicolon to end the class property, but found none
(parse)
[error] 63-63: expected a semicolon to end the class property, but found none
(parse)
[error] 63-63: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found ')'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 64-64: expected a semicolon to end the class property, but found none
(parse)
[error] 64-64: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found '.'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 64-64: Expected a parameter but instead found '('.
Expected a parameter here.
(parse)
[error] 64-64: expected
,
but instead foundresolvedUser
Remove resolvedUser
(parse)
[error] 64-64: Expected a class method body but instead found '=>'.
Expected a class method body here.
(parse)
[error] 65-65: expected a semicolon to end the class property, but found none
(parse)
[error] 65-65: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found '.'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 65-65: expected a semicolon to end the class property, but found none
(parse)
[error] 65-65: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found ')'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 66-66: Expected a statement but instead found ').catch((error) =>'.
Expected a statement here.
(parse)
[error] 68-68: Expected a statement but instead found ')'.
Expected a statement here.
(parse)
[error] 69-69: Expected a statement but instead found '} else'.
Expected a statement here.
(parse)
[error] 63-63: Duplicate class member name "user"
(lint/suspicious/noDuplicateClassMembers)
[error] 64-64: Duplicate class member name "user"
(lint/suspicious/noDuplicateClassMembers)
[error] 65-65: Duplicate private class member "#store"
(syntax/correctness/noDuplicatePrivateClassMembers)
[error] 64-64: Do not add then to a class.
(lint/suspicious/noThenProperty)
[error] 66-68: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
[error] 69-71: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
infrastructure/eid-wallet/src/routes/(auth)/verify/store.ts (1)
5-7
: Initialize writable stores with explicit null valuesFor consistency and clarity, consider initializing all nullable stores with explicit
null
values.-export const DocFront = writable<string | null>(); -export const Selfie = writable<string | null>(); -export const verificaitonId = writable<string | null>(); +export const DocFront = writable<string | null>(null); +export const Selfie = writable<string | null>(null); +export const verificationId = writable<string | null>(null);infrastructure/evault-provisioner/src/controllers/VerificationController.ts (2)
1-2
: Use import type for type-only importsThese imports are only used as types and should use
import type
syntax.-import { Request, Response } from "express"; -import { VerificationService } from "../services/VerificationService"; +import type { Request, Response } from "express"; +import type { VerificationService } from "../services/VerificationService";🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
[error] 2-2: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
12-20
: Remove unnecessary axios interceptorThe response interceptor doesn't add any functionality and can be removed.
-veriffClient.interceptors.response.use( - (response) => { - return response; - }, - async function (error) { - if (!error.response) return Promise.reject(error); - return Promise.reject(error); - }, -);🧰 Tools
🪛 Biome (1.9.4)
[error] 16-19: This function expression can be turned into an arrow function.
Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.(lint/complexity/useArrowFunction)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
infrastructure/eid-wallet/src-tauri/gen/apple/eid-wallet.xcodeproj/project.pbxproj
is excluded by!**/gen/**
infrastructure/eid-wallet/static/images/CameraCircle.svg
is excluded by!**/*.svg
infrastructure/eid-wallet/static/images/CameraFrame.svg
is excluded by!**/*.svg
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (33)
infrastructure/eid-wallet/package.json
(1 hunks)infrastructure/eid-wallet/src/lib/fragments/IdentityCard/IdentityCard.svelte
(1 hunks)infrastructure/eid-wallet/src/lib/global/controllers/evault.ts
(1 hunks)infrastructure/eid-wallet/src/lib/global/controllers/user.ts
(2 hunks)infrastructure/eid-wallet/src/lib/global/state.ts
(2 hunks)infrastructure/eid-wallet/src/lib/ui/Button/ButtonAction.svelte
(1 hunks)infrastructure/eid-wallet/src/lib/utils/capitalize.ts
(1 hunks)infrastructure/eid-wallet/src/lib/utils/index.ts
(1 hunks)infrastructure/eid-wallet/src/routes/(app)/ePassport/+page.svelte
(1 hunks)infrastructure/eid-wallet/src/routes/(app)/main/+page.svelte
(3 hunks)infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte
(1 hunks)infrastructure/eid-wallet/src/routes/(auth)/e-passport/+page.svelte
(3 hunks)infrastructure/eid-wallet/src/routes/(auth)/review/+page.svelte
(1 hunks)infrastructure/eid-wallet/src/routes/(auth)/verify/+page.svelte
(1 hunks)infrastructure/eid-wallet/src/routes/(auth)/verify/steps/passport.svelte
(1 hunks)infrastructure/eid-wallet/src/routes/(auth)/verify/steps/selfie.svelte
(1 hunks)infrastructure/eid-wallet/src/routes/(auth)/verify/store.ts
(1 hunks)infrastructure/eid-wallet/src/routes/+layout.svelte
(2 hunks)infrastructure/eid-wallet/svelte.config.js
(1 hunks)infrastructure/evault-provisioner/package.json
(1 hunks)infrastructure/evault-provisioner/src/config/database.ts
(1 hunks)infrastructure/evault-provisioner/src/controllers/VerificationController.ts
(1 hunks)infrastructure/evault-provisioner/src/entities/Verification.ts
(1 hunks)infrastructure/evault-provisioner/src/index.ts
(4 hunks)infrastructure/evault-provisioner/src/migrations/1748932757644-migration.ts
(1 hunks)infrastructure/evault-provisioner/src/migrations/1748966722767-migration.ts
(1 hunks)infrastructure/evault-provisioner/src/migrations/1748968097591-migration.ts
(1 hunks)infrastructure/evault-provisioner/src/services/VerificationService.ts
(1 hunks)infrastructure/evault-provisioner/src/utils/eventEmitter.ts
(1 hunks)infrastructure/evault-provisioner/src/utils/hmac.ts
(1 hunks)infrastructure/evault-provisioner/tsconfig.json
(2 hunks)platforms/registry/package.json
(2 hunks)platforms/registry/src/index.ts
(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
infrastructure/eid-wallet/src/lib/global/state.ts (1)
infrastructure/eid-wallet/src/lib/global/controllers/evault.ts (1)
VaultController
(3-42)
infrastructure/evault-provisioner/src/controllers/VerificationController.ts (3)
infrastructure/evault-provisioner/src/services/VerificationService.ts (1)
VerificationService
(4-50)infrastructure/evault-provisioner/src/utils/eventEmitter.ts (1)
eventEmitter
(3-3)infrastructure/evault-provisioner/src/utils/hmac.ts (1)
createHmacSignature
(3-7)
🪛 Biome (1.9.4)
infrastructure/evault-provisioner/src/utils/eventEmitter.ts
[error] 1-1: A Node.js builtin module should be imported with the node: protocol.
Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.
(lint/style/useNodejsImportProtocol)
infrastructure/evault-provisioner/src/migrations/1748966722767-migration.ts
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.
(lint/style/useImportType)
infrastructure/eid-wallet/src/lib/global/controllers/evault.ts
[error] 13-13: expected )
but instead found ,
Remove ,
(parse)
[error] 15-15: expected a semicolon to end the class property, but found none
(parse)
[error] 15-15: expected a semicolon to end the class property, but found none
(parse)
[error] 15-15: expected a semicolon to end the class property, but found none
(parse)
[error] 15-15: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found ')'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 17-17: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found '.'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 17-17: Expected a parameter but instead found '('.
Expected a parameter here.
(parse)
[error] 17-17: expected ,
but instead found resolvedUser
Remove resolvedUser
(parse)
[error] 17-17: Expected a class method body but instead found '=>'.
Expected a class method body here.
(parse)
[error] 18-18: expected a semicolon to end the class property, but found none
(parse)
[error] 18-18: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found '.'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 18-18: expected a semicolon to end the class property, but found none
(parse)
[error] 18-18: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found ')'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 19-20: Expected a statement but instead found ')
.catch((error) =>'.
Expected a statement here.
(parse)
[error] 22-22: Expected a statement but instead found ')'.
Expected a statement here.
(parse)
[error] 23-23: Expected a statement but instead found '} else'.
Expected a statement here.
(parse)
[error] 26-28: Expected a statement but instead found '}
get vault()'.
Expected a statement here.
(parse)
[error] 29-40: Illegal return statement outside of a function
(parse)
[error] 41-42: Expected a statement but instead found '}'.
Expected a statement here.
(parse)
[error] 15-15: Duplicate class member name "vault"
(lint/suspicious/noDuplicateClassMembers)
[error] 16-16: Duplicate class member name "vault"
(lint/suspicious/noDuplicateClassMembers)
[error] 18-18: Duplicate private class member "#store"
(syntax/correctness/noDuplicatePrivateClassMembers)
[error] 17-17: Do not add then to a class.
(lint/suspicious/noThenProperty)
[error] 20-22: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
[error] 23-25: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
[error] 28-41: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
infrastructure/evault-provisioner/src/config/database.ts
[error] 4-4: A Node.js builtin module should be imported with the node: protocol.
Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.
(lint/style/useNodejsImportProtocol)
infrastructure/evault-provisioner/src/services/VerificationService.ts
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.
(lint/style/useImportType)
[error] 2-2: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.
(lint/style/useImportType)
infrastructure/evault-provisioner/src/utils/hmac.ts
[error] 1-1: A Node.js builtin module should be imported with the node: protocol.
Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.
(lint/style/useNodejsImportProtocol)
[error] 3-3: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 10-10: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
infrastructure/evault-provisioner/src/migrations/1748968097591-migration.ts
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.
(lint/style/useImportType)
infrastructure/eid-wallet/src/lib/global/controllers/user.ts
[error] 61-61: expected )
but instead found ,
Remove ,
(parse)
[error] 89-89: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 90-90: expected ,
but instead found :
Remove :
(parse)
[error] 91-91: expected ,
but instead found |
Remove |
(parse)
[error] 94-94: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 108-108: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 108-108: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 109-120: Illegal return statement outside of a function
(parse)
[error] 94-106: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
[error] 108-121: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
infrastructure/evault-provisioner/src/migrations/1748932757644-migration.ts
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.
(lint/style/useImportType)
infrastructure/evault-provisioner/src/index.ts
[error] 8-8: A Node.js builtin module should be imported with the node: protocol.
Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.
(lint/style/useNodejsImportProtocol)
[error] 2-2: Some named imports are only used as types.
This import is only used as a type.
This import is only used as a type.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.
(lint/style/useImportType)
[error] 3-3: Some named imports are only used as types.
This import is only used as a type.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Add inline type keywords.
(lint/style/useImportType)
[error] 100-100: Do not use template literals if interpolation and special-character handling are not needed.
Unsafe fix: Replace with string literal
(lint/style/noUnusedTemplateLiteral)
infrastructure/evault-provisioner/src/controllers/VerificationController.ts
[error] 16-19: This function expression can be turned into an arrow function.
Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.
(lint/complexity/useArrowFunction)
[error] 25-25: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 46-46: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.
(lint/style/useImportType)
[error] 2-2: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.
(lint/style/useImportType)
🔇 Additional comments (32)
platforms/registry/package.json (1)
4-4
: LGTM: Description update aligns with vault provisioning focus.The updated description accurately reflects the service's role in managing vault entries, which is consistent with the PR objectives for evault provisioning.
infrastructure/eid-wallet/src/lib/ui/Button/ButtonAction.svelte (1)
109-109
: LGTM: Consistent comment formatting.Good practice to maintain consistent formatting by removing the extra space in the HTML comment.
infrastructure/evault-provisioner/tsconfig.json (2)
4-4
: LGTM: Module system change supports Node.js backend.Changing from ESNext to commonjs is appropriate for a Node.js backend service and aligns with TypeORM requirements.
14-15
: LGTM: Decorator support enables TypeORM integration.Adding experimental decorators and decorator metadata emission is essential for TypeORM entities and dependency injection, supporting the new verification services mentioned in the AI summary.
infrastructure/eid-wallet/src/routes/+layout.svelte (1)
105-105
: LGTM! Layout changes support dynamic content well.The addition of
h-[100dvh]
andoverflow-scroll
classes properly sets up the layout for full viewport height with scrolling capability, which aligns with the dynamic data-driven UI components mentioned in the summary.infrastructure/eid-wallet/src/lib/utils/index.ts (1)
3-3
: LGTM! Clean utility export addition.The export follows the established pattern for utility re-exports and properly exposes the new capitalize function.
infrastructure/eid-wallet/src/lib/utils/capitalize.ts (1)
1-7
: LGTM! Solid utility implementation with minor behavior note.The capitalize function correctly handles the common use case of capitalizing words. Note that multiple consecutive spaces will be collapsed to single spaces due to the split/join operation, which is likely acceptable for UI text formatting purposes.
infrastructure/evault-provisioner/src/utils/eventEmitter.ts (1)
3-3
: LGTM! Appropriate singleton pattern for event-driven communication.The singleton EventEmitter instance is well-suited for facilitating real-time communication between the webhook endpoint and SSE clients in the verification flow.
infrastructure/eid-wallet/svelte.config.js (1)
12-14
: LGTM! Environment configuration properly set for monorepo structure.The
env.dir
configuration pointing to the project root ("../../"
) is appropriate for a monorepo setup and aligns with the new identity verification features that require environment variable access.infrastructure/eid-wallet/src/lib/global/state.ts (2)
4-4
: LGTM! Proper import added for VaultController.The import follows the established pattern and supports the new vault management functionality.
27-27
: LGTM! VaultController properly integrated into GlobalState.The
vaultController
property and initialization follow the same consistent pattern as the existingsecurityController
anduserController
. The integration maintains the singleton pattern and provides centralized access to vault operations.Also applies to: 33-33
infrastructure/eid-wallet/package.json (1)
30-32
: LGTM! Dependencies appropriately added for identity verification features.The new dependencies support the comprehensive identity verification flow:
- Veriff SDKs for identity verification services
- axios for HTTP requests to backend APIs
- dotenv for environment variable management
- svelte-loading-spinners for UI feedback
- uuid for unique identifier generation
These align well with the new verification functionality described in the PR.
Also applies to: 34-34, 37-40
infrastructure/evault-provisioner/src/migrations/1748966722767-migration.ts (1)
6-8
: LGTM! Migration properly adds documentId column to verification table.The migration correctly:
- Adds a nullable
documentId
column of typecharacter varying
- Provides proper rollback in the
down
method- Follows TypeORM migration conventions
This supports the enhanced verification system that tracks document IDs associated with verifications.
Also applies to: 10-12
infrastructure/evault-provisioner/src/migrations/1748968097591-migration.ts (2)
6-8
: Migration logic looks correct.The addition of the
consumed
boolean column withNOT NULL DEFAULT false
is well-implemented. This supports tracking whether verification records have been used, which aligns with the verification workflow described in the AI summary.
10-12
: Proper rollback implementation.The down migration correctly drops the added column, ensuring clean rollbacks.
infrastructure/evault-provisioner/package.json (4)
8-8
: Development script change looks good.The switch from
tsx watch
tots-node-dev
with--respawn --transpile-only
flags is appropriate for TypeORM-based development, providing better compatibility and faster transpilation.
11-14
: TypeORM migration scripts are well-configured.The TypeORM scripts properly reference the database configuration file and follow standard conventions for migration management.
19-26
: Dependencies align with verification workflow requirements.The added dependencies support the new verification system:
cors
: For cross-origin requests from the frontendpg
: PostgreSQL client for database operationsreflect-metadata
: Required for TypeORM decoratorstypeorm
: ORM for database management
30-35
: Development dependencies are appropriate.The type definitions and
ts-node-dev
support the development workflow changes effectively.infrastructure/eid-wallet/src/routes/(app)/ePassport/+page.svelte (2)
15-22
: Good refactoring to dynamic data fetching.The replacement of hardcoded dummy data with asynchronous fetching from the global state is a significant improvement. The pattern properly handles the async nature of data retrieval.
28-42
: Conditional rendering prevents errors.The conditional rendering based on data availability is well-implemented and prevents rendering errors when data is still loading or unavailable.
infrastructure/evault-provisioner/src/migrations/1748932757644-migration.ts (2)
7-7
: Well-designed verification table schema.The table schema is comprehensive and well-designed:
- UUID primary key with auto-generation for distributed systems
- JSONB data field for flexible verification data storage
- Proper timestamp handling with automatic defaults
- Optional fields appropriately defined
10-12
: Clean rollback implementation.The down migration properly drops the entire table, ensuring complete rollback capability.
infrastructure/eid-wallet/src/routes/(auth)/review/+page.svelte (2)
16-19
: Excellent implementation of dynamic vault data loading.The
onMount
function properly fetches vault data asynchronously and updates theename
state. This replaces hardcoded data with live vault information.
31-31
: Good use of loading state for better UX.The template literal with fallback text "Loading..." provides good user feedback while vault data is being fetched asynchronously.
infrastructure/evault-provisioner/src/config/database.ts (1)
9-17
: Verify database connection security in production.The database configuration looks appropriate. Ensure that in production environments:
PROVISIONER_DATABASE_URL
is properly secured and not logged- The default fallback URL is only used in development
- Database credentials use proper authentication mechanisms
infrastructure/eid-wallet/src/lib/global/controllers/evault.ts (1)
3-42
: Well-implemented async vault controller with good error handling.The
VaultController
class provides a clean interface for managing vault data with the Tauri store. Key strengths:
- Proper encapsulation with private store instance
- Handles both direct values and promises in the setter
- Comprehensive error handling with logging
- Async getter that gracefully handles missing data
The static analysis errors appear to be false positives from the linter not correctly parsing TypeScript class property getter/setter syntax.
🧰 Tools
🪛 Biome (1.9.4)
[error] 13-13: expected
)
but instead found,
Remove ,
(parse)
[error] 15-15: expected a semicolon to end the class property, but found none
(parse)
[error] 15-15: expected a semicolon to end the class property, but found none
(parse)
[error] 15-15: expected a semicolon to end the class property, but found none
(parse)
[error] 15-15: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found ')'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 17-17: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found '.'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 17-17: Expected a parameter but instead found '('.
Expected a parameter here.
(parse)
[error] 17-17: expected
,
but instead foundresolvedUser
Remove resolvedUser
(parse)
[error] 17-17: Expected a class method body but instead found '=>'.
Expected a class method body here.
(parse)
[error] 18-18: expected a semicolon to end the class property, but found none
(parse)
[error] 18-18: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found '.'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 18-18: expected a semicolon to end the class property, but found none
(parse)
[error] 18-18: Expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found ')'.
Expected an identifier, a string literal, a number literal, a private field name, or a computed name here.
(parse)
[error] 19-20: Expected a statement but instead found ')
.catch((error) =>'.Expected a statement here.
(parse)
[error] 22-22: Expected a statement but instead found ')'.
Expected a statement here.
(parse)
[error] 23-23: Expected a statement but instead found '} else'.
Expected a statement here.
(parse)
[error] 26-28: Expected a statement but instead found '}
get vault()'.
Expected a statement here.
(parse)
[error] 29-40: Illegal return statement outside of a function
(parse)
[error] 41-42: Expected a statement but instead found '}'.
Expected a statement here.
(parse)
[error] 15-15: Duplicate class member name "vault"
(lint/suspicious/noDuplicateClassMembers)
[error] 16-16: Duplicate class member name "vault"
(lint/suspicious/noDuplicateClassMembers)
[error] 18-18: Duplicate private class member "#store"
(syntax/correctness/noDuplicatePrivateClassMembers)
[error] 17-17: Do not add then to a class.
(lint/suspicious/noThenProperty)
[error] 20-22: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
[error] 23-25: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
[error] 28-41: This block statement doesn't serve any purpose and can be safely removed.
Standalone block statements without any block-level declarations are redundant in JavaScript and can be removed to simplify the code.
(lint/complexity/noUselessLoneBlockStatements)
infrastructure/eid-wallet/src/lib/fragments/IdentityCard/IdentityCard.svelte (2)
120-120
: Good addition of capitalize class for better formatting.The addition of the
capitalize
class improves the user experience by properly formatting field names in the ePassport variant.
113-113
:✅ Verification successful
Verify the removal of "@" prefix is intentional.
The userId display no longer includes the "@" prefix. Ensure this change aligns with the design requirements and doesn't break consistency with other parts of the application.
🏁 Script executed:
#!/bin/bash # Search for other usages of userId to check consistency rg -A 2 -B 2 "userId.*@" --type svelteLength of output: 71
🏁 Script executed:
#!/bin/bash # Search all .svelte files for occurrences of userId with surrounding context rg --context 2 "userId" -g '*.svelte' -nLength of output: 2875
No “@” prefix found for userId in codebase — removal is consistent
I searched every
.svelte
file for occurrences ofuserId
paired with an “@” prefix and found none. AllIdentityCard
usages now pass the raw string (e.g.{ename}
) without prepending “@”.• No instances of
@${userId}
or similar patterns in any.svelte
file
• All<IdentityCard>
props useuserId={…}
directlySince the change is consistent across the codebase, it’s safe to consider the “@” removal intentional and resolve this comment.
infrastructure/eid-wallet/src/routes/(app)/main/+page.svelte (1)
55-55
: Good implementation of loading state for ename.The fallback to "Loading..." while data is being fetched provides good user feedback.
platforms/registry/src/index.ts (1)
80-88
: Good addition of the entropy endpoint with proper error handling.The re-addition of the
/entropy
endpoint with improved formatting and consistent error handling enhances the API's functionality.infrastructure/evault-provisioner/src/index.ts (1)
30-33
:❓ Verification inconclusive
Large payload limit may pose security risks
The 50MB limit for JSON and URL-encoded payloads is quite large and could be exploited for DoS attacks. Consider if this large limit is necessary for your use case.
What's the expected maximum size of verification data and documents? If significantly less than 50MB, consider reducing this limit to a more reasonable value.
🏁 Script executed:
#!/bin/bash # Display initial portion of index.ts to understand endpoints and payload usage sed -n '1,200p' infrastructure/evault-provisioner/src/index.tsLength of output: 5330
🏁 Script executed:
#!/bin/bash # Locate and display VerificationController to inspect routes and payload usage FILE=$(fd 'VerificationController.ts' -u) if [ -z "$FILE" ]; then echo "VerificationController.ts not found" exit 1 fi echo "Found: $FILE" sed -n '1,200p' "$FILE"Length of output: 7414
Review payload limits in index.ts
The 50 MB limits for JSON and URL-encoded bodies (in infrastructure/evault-provisioner/src/index.ts lines 30–33) may be excessive and open the service to DoS via oversized payloads (e.g. base64-encoded images).
• Confirm your最大expected request size—for instance, the largest document or image you’ll send (typically well under 50 MB).
• If your real-world payloads are significantly smaller, reduce these limits to the minimum safe threshold (e.g. 5 MB).Lines to adjust:
// Increase JSON payload limit app.use(express.json({ limit: "50mb" })); // Increase URL-encoded payload limit app.use(express.urlencoded({ limit: "50mb", extended: true }));
export function verifyHmacSignature( | ||
body: Record<string, any>, | ||
signature: string, | ||
secret: string, | ||
) { | ||
const expectedSignature = createHmacSignature(body, secret); | ||
return expectedSignature === signature; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve signature verification security and type safety.
Two improvements needed:
- Replace
any
type withunknown
for better type safety - Use timing-safe comparison to prevent timing attacks
export function verifyHmacSignature(
- body: Record<string, any>,
+ body: Record<string, unknown>,
signature: string,
secret: string,
) {
+ const crypto = require("node:crypto");
const expectedSignature = createHmacSignature(body, secret);
- return expectedSignature === signature;
+ return crypto.timingSafeEqual(
+ Buffer.from(expectedSignature, "hex"),
+ Buffer.from(signature, "hex")
+ );
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export function verifyHmacSignature( | |
body: Record<string, any>, | |
signature: string, | |
secret: string, | |
) { | |
const expectedSignature = createHmacSignature(body, secret); | |
return expectedSignature === signature; | |
} | |
export function verifyHmacSignature( | |
body: Record<string, unknown>, | |
signature: string, | |
secret: string, | |
) { | |
const crypto = require("node:crypto"); | |
const expectedSignature = createHmacSignature(body, secret); | |
return crypto.timingSafeEqual( | |
Buffer.from(expectedSignature, "hex"), | |
Buffer.from(signature, "hex") | |
); | |
} |
🧰 Tools
🪛 Biome (1.9.4)
[error] 10-10: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
🤖 Prompt for AI Agents
In infrastructure/evault-provisioner/src/utils/hmac.ts around lines 9 to 16,
replace the type of the `body` parameter from `Record<string, any>` to
`Record<string, unknown>` to improve type safety. Additionally, change the
signature comparison from a simple equality check to a timing-safe comparison
method, such as using `crypto.timingSafeEqual`, to prevent timing attacks during
HMAC verification.
"flag-icons": "^7.3.2", | ||
"tailwind-merge": "^3.0.2" | ||
"import": "^0.0.6", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify the "import" package dependency.
The import
package at version ^0.0.6
appears unusual and potentially problematic. This package name is very generic and the version suggests it might be outdated or incorrect.
🏁 Script executed:
#!/bin/bash
# Description: Check if the "import" package is legitimate and current
# Expected: Verify package exists, check its purpose, and validate version
# Check package info on npm
npm view import versions --json
npm view import description
npm view import repository
Length of output: 257
🏁 Script executed:
#!/bin/bash
# Search for any direct imports of the "import" package in the codebase
rg -n "require\(['\"]import['\"]"
rg -n "from ['\"]import['\"] import"
Length of output: 82
🏁 Script executed:
#!/bin/bash
# Inspect the 'scripts' and 'bin' sections in infrastructure/eid-wallet/package.json
jq '{scripts, bin}' infrastructure/eid-wallet/package.json
Length of output: 717
Remove unused “import” dependency
The “import” package (v^0.0.6) isn’t referenced anywhere in your codebase or npm scripts, so it appears to be unused. Please either remove it from infrastructure/eid-wallet/package.json or document why it’s needed.
• File: infrastructure/eid-wallet/package.json
– Line with "import": "^0.0.6"
🤖 Prompt for AI Agents
In infrastructure/eid-wallet/package.json at line 36, the "import" package
dependency with version "^0.0.6" is not used anywhere in the codebase or npm
scripts. Remove this dependency line from the package.json file to clean up
unused packages, unless there is a specific documented reason to keep it.
usedStorage={15} | ||
totalStorage={100} | ||
/> | ||
<IdentityCard variant="eVault" usedStorage={15} totalStorage={100} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use dynamic vault data instead of hardcoded values.
The eVault component still uses static storage values (15, 100) while other components have been updated to use dynamic data. This creates inconsistency.
- <IdentityCard variant="eVault" usedStorage={15} totalStorage={100} />
+ <IdentityCard variant="eVault" usedStorage={vaultData?.usedStorage ?? 0} totalStorage={vaultData?.totalStorage ?? 100} />
You'll need to make the vault data available in the component scope.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
<IdentityCard variant="eVault" usedStorage={15} totalStorage={100} /> | |
<IdentityCard | |
variant="eVault" | |
usedStorage={vaultData?.usedStorage ?? 0} | |
totalStorage={vaultData?.totalStorage ?? 100} | |
/> |
🤖 Prompt for AI Agents
In infrastructure/eid-wallet/src/routes/(app)/main/+page.svelte at line 68,
replace the hardcoded storage values (15 and 100) passed to the IdentityCard
component with dynamic vault data available in the component's scope. Ensure
that the dynamic values for usedStorage and totalStorage are properly fetched or
passed into the component so the IdentityCard reflects current vault storage
information consistently with other components.
export class VerificationController { | ||
constructor(private readonly verificationService: VerificationService) {} | ||
|
||
registerRoutes(app: any) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace any type with proper Express type
Use proper typing instead of any
for better type safety.
- registerRoutes(app: any) {
+ registerRoutes(app: Express.Application) {
Add the import at the top:
import type { Application } from "express";
🧰 Tools
🪛 Biome (1.9.4)
[error] 25-25: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
🤖 Prompt for AI Agents
In infrastructure/evault-provisioner/src/controllers/VerificationController.ts
at line 25, replace the parameter type 'any' in the registerRoutes method with
the proper Express type 'Application'. Import 'Application' from 'express' at
the top of the file using 'import type { Application } from "express";' and
update the method signature to use 'app: Application' for better type safety.
const handler = (data: any) => { | ||
console.log("hi?"); | ||
res.write(`data: ${JSON.stringify(data)}\n\n`); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove debug console.log and fix type
Remove debug statement and add proper typing.
- const handler = (data: any) => {
- console.log("hi?");
+ const handler = (data: Record<string, any>) => {
res.write(`data: ${JSON.stringify(data)}\n\n`);
};
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const handler = (data: any) => { | |
console.log("hi?"); | |
res.write(`data: ${JSON.stringify(data)}\n\n`); | |
}; | |
const handler = (data: Record<string, any>) => { | |
res.write(`data: ${JSON.stringify(data)}\n\n`); | |
}; |
🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
🤖 Prompt for AI Agents
In infrastructure/evault-provisioner/src/controllers/VerificationController.ts
between lines 46 and 49, remove the debug console.log statement "hi?" and
replace the parameter type of the handler function from any to a more specific
type that matches the expected data structure being handled. This improves code
cleanliness and type safety.
app.patch("/verification/:id", async (req: Request, res: Response) => { | ||
const verification = await this.verificationService.findById( | ||
req.params.id, | ||
); | ||
const body = { | ||
verification: { | ||
status: "submitted", | ||
}, | ||
}; | ||
const signature = createHmacSignature( | ||
body, | ||
process.env.VERIFF_HMAC_KEY as string, | ||
); | ||
await veriffClient.patch( | ||
`/v1/sessions/${verification?.veriffId}`, | ||
body, | ||
{ | ||
headers: { | ||
"X-HMAC-SIGNATURE": signature, | ||
"X-AUTH-CLIENT": process.env.PUBLIC_VERIFF_KEY, | ||
}, | ||
}, | ||
); | ||
res.sendStatus(201); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add null check for verification
The endpoint uses optional chaining but doesn't handle the case where verification is not found.
app.patch("/verification/:id", async (req: Request, res: Response) => {
const verification = await this.verificationService.findById(
req.params.id,
);
+
+ if (!verification) {
+ return res.status(404).json({ error: "Verification not found" });
+ }
+
const body = {
verification: {
status: "submitted",
},
};
const signature = createHmacSignature(
body,
process.env.VERIFF_HMAC_KEY as string,
);
- await veriffClient.patch(
- `/v1/sessions/${verification?.veriffId}`,
+
+ try {
+ await veriffClient.patch(
+ `/v1/sessions/${verification.veriffId}`,
body,
{
headers: {
"X-HMAC-SIGNATURE": signature,
"X-AUTH-CLIENT": process.env.PUBLIC_VERIFF_KEY,
},
},
);
res.sendStatus(201);
+ } catch (error) {
+ console.error("Failed to update verification status:", error);
+ return res.status(500).json({ error: "Failed to update verification status" });
+ }
});
🤖 Prompt for AI Agents
In infrastructure/evault-provisioner/src/controllers/VerificationController.ts
around lines 161 to 185, the code uses optional chaining on verification but
does not handle the case when verification is null or undefined. Add a null
check after fetching verification; if it is not found, respond with an
appropriate error status (e.g., 404) and message, and only proceed with the
patch request if verification exists.
// Webhook for verification decisions | ||
app.post( | ||
"/verification/decisions", | ||
async (req: Request, res: Response) => { | ||
const body = req.body; | ||
console.log(body); | ||
const id = body.vendorData; | ||
|
||
const verification = | ||
await this.verificationService.findById(id); | ||
if (!verification) { | ||
return res | ||
.status(404) | ||
.json({ error: "Verification not found" }); | ||
} | ||
|
||
const affirmativeStatusTypes = [ | ||
"approved", | ||
"declined", | ||
"expired", | ||
"abandoned", | ||
]; | ||
if ( | ||
affirmativeStatusTypes.includes( | ||
body.data.verification.decision, | ||
) | ||
) { | ||
const approved = | ||
body.data.verification.decision === "approved"; | ||
await this.verificationService.findByIdAndUpdate(id, { | ||
approved, | ||
data: { | ||
person: body.data.verification.person, | ||
document: body.data.verification.document, | ||
}, | ||
documentId: | ||
body.data.verification.document.number.value, | ||
}); | ||
} | ||
|
||
eventEmitter.emit(id, { | ||
reason: body.data.verification.reason, | ||
status: body.data.verification.decision, | ||
person: body.data.verification.person ?? null, | ||
document: body.data.verification.document, | ||
}); | ||
|
||
return res.json({ success: true }); | ||
}, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Add HMAC signature verification for webhook security
The webhook endpoint lacks HMAC signature verification, which is critical for ensuring the authenticity of webhook calls from Veriff. This is a security vulnerability that could allow unauthorized parties to manipulate verification decisions.
Additionally, remove the debug console.log statement.
app.post(
"/verification/decisions",
async (req: Request, res: Response) => {
+ // Verify HMAC signature
+ const signature = req.headers['x-hmac-signature'] as string;
+ if (!signature) {
+ return res.status(401).json({ error: "Missing signature" });
+ }
+
+ const expectedSignature = createHmacSignature(
+ req.body,
+ process.env.VERIFF_WEBHOOK_SECRET as string
+ );
+
+ if (signature !== expectedSignature) {
+ return res.status(401).json({ error: "Invalid signature" });
+ }
+
const body = req.body;
- console.log(body);
const id = body.vendorData;
const verification =
await this.verificationService.findById(id);
if (!verification) {
return res
.status(404)
.json({ error: "Verification not found" });
}
// ... rest of the code
Verify that Veriff sends HMAC signatures with their webhooks:
🌐 Web query:
Does Veriff API send HMAC signatures in webhook headers for verification decision webhooks?
💡 Result:
Yes, Veriff's API includes HMAC signatures in the headers of verification decision webhooks. These signatures are provided in the X-HMAC-SIGNATURE
header, allowing you to verify the authenticity and integrity of the webhook payloads. (developers.veriff.com)
To validate the webhook requests:
-
Extract the Signature and Timestamp: Retrieve the
X-HMAC-SIGNATURE
header from the incoming request. This header contains the timestamp and the HMAC signature, formatted ast=<timestamp>,s=<signature>
. -
Prepare the Payload: Concatenate the timestamp and the request body, separated by a dot (
.
). For example, if the timestamp is1582267948
and the request body is{"verification": {"status": "approved"}}
, the payload would be1582267948.{"verification": {"status": "approved"}}
. -
Generate the Expected Signature: Use your shared secret key to compute an HMAC-SHA256 hash of the prepared payload. This can be done using cryptographic libraries available in your programming language.
-
Compare the Signatures: Compare the computed HMAC signature with the one extracted from the
X-HMAC-SIGNATURE
header. If they match, the request is authentic and has not been tampered with.
For detailed information and code examples on verifying webhook signatures, refer to Veriff's developer documentation. (developers.veriff.com)
Citations:
- 1: https://developers.veriff.com//?utm_source=openai
- 2: https://developers.veriff.com//?utm_source=openai
Implement HMAC-SHA256 webhook signature verification
Ensure that only genuine Veriff webhooks are processed by:
- Removing the debug
console.log(body)
. - Extracting and parsing the
X-HMAC-SIGNATURE
header (t=<timestamp>,s=<signature>
). - Concatenating
<timestamp>.<JSON-stringified body>
, computing an HMAC-SHA256 hash with yourVERIFF_WEBHOOK_SECRET
, and comparing it to the provided signature. - Returning HTTP 401 on missing or invalid signatures.
- (Optional) Enforcing a maximum age on the timestamp (e.g. 5 minutes) to mitigate replay attacks.
Apply the following diff in
infrastructure/evault-provisioner/src/controllers/VerificationController.ts
(around lines 187–236):
@@ -187,6 +187,24 @@ app.post(
"/verification/decisions",
async (req: Request, res: Response) => {
+ // HMAC signature verification (t=<timestamp>,s=<signature>)
+ const signatureHeader = req.headers['x-hmac-signature'] as string;
+ if (!signatureHeader) {
+ return res.status(401).json({ error: "Missing signature" });
+ }
+ const parts = signatureHeader.split(',');
+ const timestamp = parts[0].split('=')[1];
+ const signature = parts[1].split('=')[1];
+
+ // Optional: reject if timestamp is too old
+ // const age = Date.now()/1000 - Number(timestamp);
+ // if (age > 300) return res.status(401).json({ error: "Stale request" });
+
+ const payload = `${timestamp}.${JSON.stringify(req.body)}`;
+ const expected = crypto
+ .createHmac('sha256', process.env.VERIFF_WEBHOOK_SECRET!)
+ .update(payload)
+ .digest('hex');
+ if (signature !== expected) {
+ return res.status(401).json({ error: "Invalid signature" });
+ }
+
const body = req.body;
- console.log(body);
const id = body.vendorData;
const verification =
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// Webhook for verification decisions | |
app.post( | |
"/verification/decisions", | |
async (req: Request, res: Response) => { | |
const body = req.body; | |
console.log(body); | |
const id = body.vendorData; | |
const verification = | |
await this.verificationService.findById(id); | |
if (!verification) { | |
return res | |
.status(404) | |
.json({ error: "Verification not found" }); | |
} | |
const affirmativeStatusTypes = [ | |
"approved", | |
"declined", | |
"expired", | |
"abandoned", | |
]; | |
if ( | |
affirmativeStatusTypes.includes( | |
body.data.verification.decision, | |
) | |
) { | |
const approved = | |
body.data.verification.decision === "approved"; | |
await this.verificationService.findByIdAndUpdate(id, { | |
approved, | |
data: { | |
person: body.data.verification.person, | |
document: body.data.verification.document, | |
}, | |
documentId: | |
body.data.verification.document.number.value, | |
}); | |
} | |
eventEmitter.emit(id, { | |
reason: body.data.verification.reason, | |
status: body.data.verification.decision, | |
person: body.data.verification.person ?? null, | |
document: body.data.verification.document, | |
}); | |
return res.json({ success: true }); | |
}, | |
); | |
// Webhook for verification decisions | |
app.post( | |
"/verification/decisions", | |
async (req: Request, res: Response) => { | |
+ // HMAC signature verification (t=<timestamp>,s=<signature>) | |
+ const signatureHeader = req.headers['x-hmac-signature'] as string; | |
+ if (!signatureHeader) { | |
+ return res.status(401).json({ error: "Missing signature" }); | |
+ } | |
+ const parts = signatureHeader.split(','); | |
+ const timestamp = parts[0].split('=')[1]; | |
+ const signature = parts[1].split('=')[1]; | |
+ | |
+ // Optional: reject if timestamp is too old | |
+ // const age = Date.now()/1000 - Number(timestamp); | |
+ // if (age > 300) return res.status(401).json({ error: "Stale request" }); | |
+ | |
+ const payload = `${timestamp}.${JSON.stringify(req.body)}`; | |
+ const expected = crypto | |
+ .createHmac('sha256', process.env.VERIFF_WEBHOOK_SECRET!) | |
+ .update(payload) | |
+ .digest('hex'); | |
+ if (signature !== expected) { | |
+ return res.status(401).json({ error: "Invalid signature" }); | |
+ } | |
+ | |
const body = req.body; | |
- console.log(body); | |
const id = body.vendorData; | |
const verification = | |
await this.verificationService.findById(id); | |
if (!verification) { | |
return res | |
.status(404) | |
.json({ error: "Verification not found" }); | |
} | |
const affirmativeStatusTypes = [ | |
"approved", | |
"declined", | |
"expired", | |
"abandoned", | |
]; | |
if ( | |
affirmativeStatusTypes.includes( | |
body.data.verification.decision, | |
) | |
) { | |
const approved = | |
body.data.verification.decision === "approved"; | |
await this.verificationService.findByIdAndUpdate(id, { | |
approved, | |
data: { | |
person: body.data.verification.person, | |
document: body.data.verification.document, | |
}, | |
documentId: | |
body.data.verification.document.number.value, | |
}); | |
} | |
eventEmitter.emit(id, { | |
reason: body.data.verification.reason, | |
status: body.data.verification.decision, | |
person: body.data.verification.person ?? null, | |
document: body.data.verification.document, | |
}); | |
return res.json({ success: true }); | |
}, | |
); |
🤖 Prompt for AI Agents
In infrastructure/evault-provisioner/src/controllers/VerificationController.ts
around lines 187 to 236, remove the debug console.log statement and implement
HMAC-SHA256 verification for the webhook. Extract the X-HMAC-SIGNATURE header,
parse out the timestamp and signature, then concatenate the timestamp and the
raw JSON string of the request body separated by a dot. Compute the HMAC-SHA256
hash of this concatenated string using the VERIFF_WEBHOOK_SECRET environment
variable and compare it to the signature from the header. If the signature is
missing or invalid, respond with HTTP 401 Unauthorized. Optionally, validate
that the timestamp is recent (e.g., within 5 minutes) to prevent replay attacks
before processing the webhook logic.
app.post( | ||
"/verification/:id/media", | ||
async (req: Request, res: Response) => { | ||
const { img, type } = req.body; | ||
const types = ["document-front", "document-back", "face"]; | ||
if (!types.includes(type)) | ||
throw new Error( | ||
`Wrong type specified, accepted types are ${types}`, | ||
); | ||
const verification = await this.verificationService.findById( | ||
req.params.id, | ||
); | ||
if (!verification) throw new Error("Verification not found"); | ||
const veriffBody = { | ||
image: { | ||
context: type, | ||
content: img, | ||
}, | ||
}; | ||
|
||
const signature = createHmacSignature( | ||
veriffBody, | ||
process.env.VERIFF_HMAC_KEY as string, | ||
); | ||
await veriffClient.post( | ||
`/v1/sessions/${verification.veriffId}/media`, | ||
veriffBody, | ||
{ | ||
headers: { | ||
"X-HMAC-SIGNATURE": signature, | ||
"X-AUTH-CLIENT": process.env.PUBLIC_VERIFF_KEY, | ||
}, | ||
}, | ||
); | ||
res.sendStatus(201); | ||
}, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve error handling and add validation
The endpoint throws errors instead of returning proper HTTP responses, and lacks validation for the image content.
app.post(
"/verification/:id/media",
async (req: Request, res: Response) => {
const { img, type } = req.body;
+
+ if (!img || typeof img !== 'string') {
+ return res.status(400).json({ error: "Invalid or missing image data" });
+ }
+
const types = ["document-front", "document-back", "face"];
if (!types.includes(type))
- throw new Error(
- `Wrong type specified, accepted types are ${types}`,
- );
+ return res.status(400).json({
+ error: `Wrong type specified, accepted types are ${types.join(", ")}`
+ });
+
const verification = await this.verificationService.findById(
req.params.id,
);
- if (!verification) throw new Error("Verification not found");
+ if (!verification) {
+ return res.status(404).json({ error: "Verification not found" });
+ }
+
+ const hmacKey = process.env.VERIFF_HMAC_KEY;
+ const authClient = process.env.PUBLIC_VERIFF_KEY;
+
+ if (!hmacKey || !authClient) {
+ console.error("Missing Veriff configuration");
+ return res.status(500).json({ error: "Server configuration error" });
+ }
+
const veriffBody = {
image: {
context: type,
content: img,
},
};
const signature = createHmacSignature(
veriffBody,
- process.env.VERIFF_HMAC_KEY as string,
+ hmacKey,
);
- await veriffClient.post(
- `/v1/sessions/${verification.veriffId}/media`,
- veriffBody,
- {
- headers: {
- "X-HMAC-SIGNATURE": signature,
- "X-AUTH-CLIENT": process.env.PUBLIC_VERIFF_KEY,
+
+ try {
+ await veriffClient.post(
+ `/v1/sessions/${verification.veriffId}/media`,
+ veriffBody,
+ {
+ headers: {
+ "X-HMAC-SIGNATURE": signature,
+ "X-AUTH-CLIENT": authClient,
+ },
},
- },
- );
- res.sendStatus(201);
+ );
+ res.sendStatus(201);
+ } catch (error) {
+ console.error("Failed to upload media to Veriff:", error);
+ return res.status(500).json({ error: "Failed to upload media" });
+ }
},
);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
app.post( | |
"/verification/:id/media", | |
async (req: Request, res: Response) => { | |
const { img, type } = req.body; | |
const types = ["document-front", "document-back", "face"]; | |
if (!types.includes(type)) | |
throw new Error( | |
`Wrong type specified, accepted types are ${types}`, | |
); | |
const verification = await this.verificationService.findById( | |
req.params.id, | |
); | |
if (!verification) throw new Error("Verification not found"); | |
const veriffBody = { | |
image: { | |
context: type, | |
content: img, | |
}, | |
}; | |
const signature = createHmacSignature( | |
veriffBody, | |
process.env.VERIFF_HMAC_KEY as string, | |
); | |
await veriffClient.post( | |
`/v1/sessions/${verification.veriffId}/media`, | |
veriffBody, | |
{ | |
headers: { | |
"X-HMAC-SIGNATURE": signature, | |
"X-AUTH-CLIENT": process.env.PUBLIC_VERIFF_KEY, | |
}, | |
}, | |
); | |
res.sendStatus(201); | |
}, | |
); | |
app.post( | |
"/verification/:id/media", | |
async (req: Request, res: Response) => { | |
const { img, type } = req.body; | |
if (!img || typeof img !== 'string') { | |
return res.status(400).json({ error: "Invalid or missing image data" }); | |
} | |
const types = ["document-front", "document-back", "face"]; | |
if (!types.includes(type)) { | |
return res.status(400).json({ | |
error: `Wrong type specified, accepted types are ${types.join(", ")}` | |
}); | |
} | |
const verification = await this.verificationService.findById( | |
req.params.id, | |
); | |
if (!verification) { | |
return res.status(404).json({ error: "Verification not found" }); | |
} | |
const hmacKey = process.env.VERIFF_HMAC_KEY; | |
const authClient = process.env.PUBLIC_VERIFF_KEY; | |
if (!hmacKey || !authClient) { | |
console.error("Missing Veriff configuration"); | |
return res.status(500).json({ error: "Server configuration error" }); | |
} | |
const veriffBody = { | |
image: { | |
context: type, | |
content: img, | |
}, | |
}; | |
const signature = createHmacSignature( | |
veriffBody, | |
hmacKey, | |
); | |
try { | |
await veriffClient.post( | |
`/v1/sessions/${verification.veriffId}/media`, | |
veriffBody, | |
{ | |
headers: { | |
"X-HMAC-SIGNATURE": signature, | |
"X-AUTH-CLIENT": authClient, | |
}, | |
}, | |
); | |
res.sendStatus(201); | |
} catch (error) { | |
console.error("Failed to upload media to Veriff:", error); | |
return res.status(500).json({ error: "Failed to upload media" }); | |
} | |
}, | |
); |
🤖 Prompt for AI Agents
In infrastructure/evault-provisioner/src/controllers/VerificationController.ts
between lines 67 and 103, the endpoint currently throws errors directly and does
not validate the image content. Refactor the code to catch errors and respond
with appropriate HTTP status codes and messages instead of throwing exceptions.
Add validation to ensure the 'img' field is present and correctly formatted
before proceeding. Use try-catch blocks around the async logic and send
meaningful error responses to the client.
Docstrings generation was requested by @coodos. * #188 (comment) The following files were modified: * `infrastructure/eid-wallet/src/lib/utils/capitalize.ts` * `infrastructure/evault-provisioner/src/utils/hmac.ts`
Note Generated docstrings for this pull request at #189 |
Docstrings generation was requested by @coodos. * #188 (comment) The following files were modified: * `infrastructure/eid-wallet/src/lib/utils/capitalize.ts` * `infrastructure/evault-provisioner/src/utils/hmac.ts` Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (9)
infrastructure/eid-wallet/src/routes/(auth)/verify/+page.svelte (4)
17-17
: Fix typo in import nameThe import
verificaitonId
contains a typo and should beverificationId
.- verificaitonId, + verificationId,
33-40
: Add error handling for verification initiationThe function lacks error handling for the HTTP request and still uses the typo
verificaitonId
, both of which were flagged in previous reviews.async function handleVerification() { + try { const { data } = await axios.post( new URL("/verification", PUBLIC_PROVISIONER_URL).toString(), ); - verificaitonId.set(data.id); + verificationId.set(data.id); showVeriffModal = true; watchEventStream(data.id); + } catch (error) { + console.error("Failed to initiate verification:", error); + status.set("error"); + reason.set("Failed to initiate verification. Please try again."); + showVeriffModal = true; + } }
42-67
: Remove console.log statements and add error handlingThe function still contains debug console.log statements and lacks error handling for EventSource failures, as previously flagged.
function watchEventStream(id: string) { const sseUrl = new URL( `/verification/sessions/${id}`, PUBLIC_PROVISIONER_URL, ).toString(); const eventSource = new EventSource(sseUrl); eventSource.onopen = function (e) { - console.log("Successfully connected."); + // Connection established }; eventSource.onmessage = function (e) { const data = JSON.parse(e.data); - if (!data.status) console.log(data); - console.log("STATUS", data); status.set(data.status); reason.set(data.reason); person = data.person; document = data.document; if (data.status === "resubmission_requested") { DocFront.set(null); Selfie.set(null); } verifStep.set(2); }; + + eventSource.onerror = function (error) { + console.error("SSE connection error:", error); + eventSource.close(); + // Consider showing error to user + status.set("error"); + reason.set("Connection error. Please try again."); + }; + + return eventSource; }
71-120
: Add comprehensive error handling and resource cleanupMultiple issues remain unresolved from previous reviews: missing error handling for API calls, hardcoded timeout, typo in variable name, and lack of resource cleanup.
+ let eventSource: EventSource | null = null; + let navigationTimeout: ReturnType<typeof setTimeout> | null = null; + const NAVIGATION_DELAY = 10_000; onMount(() => { globalState = getContext<() => GlobalState>("globalState")(); handleContinue = async () => { if ($status !== "approved") return verifStep.set(0); if (!globalState) throw new Error("Global state is not defined"); loading = true; + try { globalState.userController.user = { name: capitalize( person.firstName.value + " " + person.lastName.value, ), "Date of Birth": new Date( person.dateOfBirth.value, ).toDateString(), "ID submitted": "Passport - " + person.nationality.value, "Passport Number": document.number.value, }; globalState.userController.document = { "Valid From": new Date(document.validFrom.value).toDateString(), "Valid Until": new Date( document.validUntil.value, ).toDateString(), "Verified On": new Date().toDateString(), }; const { data: { token: registryEntropy }, } = await axios.get( new URL("/entropy", PUBLIC_REGISTRY_URL).toString(), ); const { data } = await axios.post( new URL("/provision", PUBLIC_PROVISIONER_URL).toString(), { registryEntropy, namespace: uuidv4(), - verificationId: $verificaitonId, + verificationId: $verificationId, }, ); if (data.success === true) { globalState.vaultController.vault = { uri: data.uri, ename: data.w3id, }; } - setTimeout(() => { + navigationTimeout = setTimeout(() => { goto("/register"); - }, 10_000); + }, NAVIGATION_DELAY); + } catch (error) { + console.error("Failed to complete verification:", error); + loading = false; + status.set("error"); + reason.set("Failed to complete verification. Please try again."); + } }; + + // Update watchEventStream call + // In handleVerification function, store the returned EventSource: + // eventSource = watchEventStream(data.id); + + return () => { + // Cleanup on component destroy + if (eventSource) { + eventSource.close(); + } + if (navigationTimeout) { + clearTimeout(navigationTimeout); + } + }; });infrastructure/evault-provisioner/src/controllers/VerificationController.ts (5)
25-25
: Replace any type with proper Express typeUse proper typing instead of
any
for better type safety.- registerRoutes(app: any) { + registerRoutes(app: Application) {Add the import at the top:
import type { Application } from "express";🧰 Tools
🪛 Biome (1.9.4)
[error] 25-25: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
46-49
: Remove debug console.log and fix typeRemove debug statement and add proper typing.
- const handler = (data: any) => { - console.log("hi?"); + const handler = (data: Record<string, any>) => { res.write(`data: ${JSON.stringify(data)}\n\n`); };🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
67-103
: Improve error handling and add validationThe endpoint throws errors instead of returning proper HTTP responses, and lacks validation for the image content.
app.post( "/verification/:id/media", async (req: Request, res: Response) => { const { img, type } = req.body; + + if (!img || typeof img !== 'string') { + return res.status(400).json({ error: "Invalid or missing image data" }); + } + const types = ["document-front", "document-back", "face"]; if (!types.includes(type)) - throw new Error( - `Wrong type specified, accepted types are ${types}`, - ); + return res.status(400).json({ + error: `Wrong type specified, accepted types are ${types.join(", ")}` + }); + const verification = await this.verificationService.findById( req.params.id, ); - if (!verification) throw new Error("Verification not found"); + if (!verification) { + return res.status(404).json({ error: "Verification not found" }); + }
161-185
: Add null check for verificationThe endpoint uses optional chaining but doesn't handle the case where verification is not found.
app.patch("/verification/:id", async (req: Request, res: Response) => { const verification = await this.verificationService.findById( req.params.id, ); + + if (!verification) { + return res.status(404).json({ error: "Verification not found" }); + } + const body = { verification: { status: "submitted", }, }; const signature = createHmacSignature( body, process.env.VERIFF_HMAC_KEY as string, ); - await veriffClient.patch( - `/v1/sessions/${verification?.veriffId}`, + + try { + await veriffClient.patch( + `/v1/sessions/${verification.veriffId}`, body, { headers: { "X-HMAC-SIGNATURE": signature, "X-AUTH-CLIENT": process.env.PUBLIC_VERIFF_KEY, }, }, ); res.sendStatus(201); + } catch (error) { + console.error("Failed to update verification status:", error); + return res.status(500).json({ error: "Failed to update verification status" }); + } });
187-253
: Implement HMAC-SHA256 webhook signature verificationThe webhook endpoint lacks HMAC signature verification and contains debug logging.
app.post( "/verification/decisions", async (req: Request, res: Response) => { + // HMAC signature verification (t=<timestamp>,s=<signature>) + const signatureHeader = req.headers['x-hmac-signature'] as string; + if (!signatureHeader) { + return res.status(401).json({ error: "Missing signature" }); + } + const parts = signatureHeader.split(','); + const timestamp = parts[0].split('=')[1]; + const signature = parts[1].split('=')[1]; + + const payload = `${timestamp}.${JSON.stringify(req.body)}`; + const expected = crypto + .createHmac('sha256', process.env.VERIFF_WEBHOOK_SECRET!) + .update(payload) + .digest('hex'); + if (signature !== expected) { + return res.status(401).json({ error: "Invalid signature" }); + } + const body = req.body; - console.log(body); const id = body.vendorData;Also add the crypto import at the top:
import crypto from 'crypto';
🧹 Nitpick comments (5)
infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte (1)
47-49
: Enhance the delete button with better UX patternsWhile the ButtonAction implementation is correct, consider improving the user experience:
- Visual distinction - Use a destructive variant/styling
- Better placement - Consider separating from other settings
- Loading state - Show loading during deletion process
- <ButtonAction class="mt-5 w-full" callback={nukeWallet} - >Delete Account</ButtonAction - > + <div class="mt-8 pt-4 border-t border-gray-200"> + <ButtonAction + class="w-full bg-red-600 hover:bg-red-700 text-white" + callback={nukeWallet} + disabled={isDeleting} + > + {isDeleting ? 'Deleting...' : 'Delete Account'} + </ButtonAction> + </div>Note: You'll need to add an
isDeleting
reactive variable to track the deletion state.infrastructure/eid-wallet/src/routes/(auth)/verify/+page.svelte (1)
138-180
: Consider adding loading state management for verification stepsThe template handles different verification states well, but consider adding loading indicators for individual verification steps to improve user experience.
<Drawer bind:isPaneOpen={showVeriffModal}> {#if $verifStep === 0} <Passport></Passport> {:else if $verifStep === 1} <Selfie></Selfie> {:else if loading} <div class="my-20"> <div class="align-center flex w-full flex-col items-center justify-center gap-6" > <Shadow size={40} color="rgb(142, 82, 255);" /> <h3>Generating your eName</h3> </div> </div> {:else} <div class="flex flex-col gap-6"> {#if $status === "approved"} <div> <h3>Your verification was a success</h3> <p>You can now continue on to create your eName</p> </div> {:else if $status === "resubmission_requested"} <h3>Your verification failed due to the reason</h3> <p>{$reason}</p> + {:else if $status === "error"} + <h3>An error occurred</h3> + <p>{$reason}</p> {:else} <h3>Your verification failed</h3> <p>{$reason}</p> {/if} </div>infrastructure/evault-provisioner/src/controllers/VerificationController.ts (3)
1-2
: Use import type for type-only importsThe imports for
Request
,Response
, andVerificationService
are only used as types, not runtime values.-import { Request, Response } from "express"; -import { VerificationService } from "../services/VerificationService"; +import type { Request, Response } from "express"; +import type { VerificationService } from "../services/VerificationService";🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
[error] 2-2: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
12-20
: Simplify redundant response interceptorThe response interceptor doesn't add any value - it just returns the response or rejects with the same error.
-veriffClient.interceptors.response.use( - (response) => { - return response; - }, - async function (error) { - if (!error.response) return Promise.reject(error); - return Promise.reject(error); - }, -);Consider removing this interceptor entirely or adding meaningful error handling/logging if needed.
🧰 Tools
🪛 Biome (1.9.4)
[error] 16-19: This function expression can be turned into an arrow function.
Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.(lint/complexity/useArrowFunction)
222-225
: Remove debug logging from production codeDebug console.log statements should be removed from production code.
const verificationMatch = await this.verificationService.findOne({ documentId: body.data.verification.document.number.value }); - console.log("matched", verificationMatch)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte
(1 hunks)infrastructure/eid-wallet/src/routes/(auth)/verify/+page.svelte
(1 hunks)infrastructure/evault-provisioner/src/controllers/VerificationController.ts
(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
infrastructure/evault-provisioner/src/controllers/VerificationController.ts
[error] 16-19: This function expression can be turned into an arrow function.
Function expressions that don't use this can be turned into arrow functions.
Safe fix: Use an arrow function instead.
(lint/complexity/useArrowFunction)
[error] 25-25: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 46-46: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 1-1: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.
(lint/style/useImportType)
[error] 2-2: All these imports are only used as types.
Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
Safe fix: Use import type.
(lint/style/useImportType)
🔇 Additional comments (4)
infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte (4)
2-14
: LGTM - Clean import organizationThe imports are well-organized and include all necessary dependencies for the settings page functionality.
16-16
: LGTM - Proper global state accessUsing Svelte's context to access global state follows the established pattern mentioned in the AI summary.
24-26
: LGTM - Standard page title setupThe effect properly sets the page title in the runtime header.
31-45
: LGTM - Well-structured navigation buttonsThe settings navigation buttons are properly implemented with appropriate icons and routes.
function nukeWallet() { | ||
globalState.userController.user = null; | ||
globalState.securityController.clearPin(); | ||
goto("/onboarding"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add user confirmation and error handling for account deletion
The nukeWallet
function immediately deletes user data without confirmation, which could lead to accidental data loss. Consider implementing safety measures:
- User confirmation dialog - Require explicit confirmation before deletion
- Error handling - Handle potential failures in state clearing
- Async operation - Consider if backend cleanup is needed
- function nukeWallet() {
- globalState.userController.user = null;
- globalState.securityController.clearPin();
- goto("/onboarding");
- }
+ async function nukeWallet() {
+ const confirmed = confirm("Are you sure you want to delete your account? This action cannot be undone.");
+ if (!confirmed) return;
+
+ try {
+ globalState.userController.user = null;
+ globalState.securityController.clearPin();
+ // Add any additional cleanup operations here
+ goto("/onboarding");
+ } catch (error) {
+ console.error("Failed to delete account:", error);
+ // Show error message to user
+ }
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
function nukeWallet() { | |
globalState.userController.user = null; | |
globalState.securityController.clearPin(); | |
goto("/onboarding"); | |
} | |
async function nukeWallet() { | |
const confirmed = confirm("Are you sure you want to delete your account? This action cannot be undone."); | |
if (!confirmed) return; | |
try { | |
globalState.userController.user = null; | |
globalState.securityController.clearPin(); | |
// Add any additional cleanup operations here | |
goto("/onboarding"); | |
} catch (error) { | |
console.error("Failed to delete account:", error); | |
// Show error message to user | |
} | |
} |
🤖 Prompt for AI Agents
In infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte around lines
18 to 22, the nukeWallet function deletes user data immediately without
confirmation or error handling. Modify the function to first show a user
confirmation dialog and proceed only if confirmed. Add try-catch blocks to
handle any errors during user state clearing and securityController.clearPin
calls. If backend cleanup is required, make the function async and await the
necessary asynchronous operations before navigating to the onboarding page.
app.post("/verification", async (req: Request, res: Response) => { | ||
const { referenceId } = req.body; | ||
|
||
if (referenceId) { | ||
const existing = await this.verificationService.findOne({ | ||
referenceId, | ||
}); | ||
if (existing) { | ||
return res | ||
.status(409) | ||
.json({ error: "Reference ID Already Exists" }); | ||
} | ||
} | ||
|
||
const verification = await this.verificationService.create({ | ||
referenceId, | ||
}); | ||
const veriffBody = { | ||
verification: { | ||
vendorData: verification.id, | ||
}, | ||
}; | ||
const signature = createHmacSignature( | ||
veriffBody, | ||
process.env.VERIFF_HMAC_KEY as string, | ||
); | ||
const { data: veriffSession } = await veriffClient.post( | ||
"/v1/sessions", | ||
veriffBody, | ||
{ | ||
headers: { | ||
"X-HMAC-SIGNATURE": signature, | ||
"X-AUTH-CLIENT": process.env.PUBLIC_VERIFF_KEY, | ||
}, | ||
}, | ||
); | ||
await this.verificationService.findByIdAndUpdate(verification.id, { | ||
veriffId: veriffSession.verification.id, | ||
}); | ||
|
||
return res.status(201).json(verification); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for external API calls
The verification creation endpoint lacks proper error handling for the Veriff API call.
- const { data: veriffSession } = await veriffClient.post(
- "/v1/sessions",
- veriffBody,
- {
- headers: {
- "X-HMAC-SIGNATURE": signature,
- "X-AUTH-CLIENT": process.env.PUBLIC_VERIFF_KEY,
- },
- },
- );
- await this.verificationService.findByIdAndUpdate(verification.id, {
- veriffId: veriffSession.verification.id,
- });
+ try {
+ const { data: veriffSession } = await veriffClient.post(
+ "/v1/sessions",
+ veriffBody,
+ {
+ headers: {
+ "X-HMAC-SIGNATURE": signature,
+ "X-AUTH-CLIENT": process.env.PUBLIC_VERIFF_KEY,
+ },
+ },
+ );
+ await this.verificationService.findByIdAndUpdate(verification.id, {
+ veriffId: veriffSession.verification.id,
+ });
+ } catch (error) {
+ console.error("Failed to create Veriff session:", error);
+ await this.verificationService.delete(verification.id);
+ return res.status(500).json({ error: "Failed to create verification session" });
+ }
🤖 Prompt for AI Agents
In infrastructure/evault-provisioner/src/controllers/VerificationController.ts
between lines 118 and 159, the code calls the external Veriff API without error
handling, which can cause unhandled exceptions. Wrap the Veriff API call and
subsequent update in a try-catch block to catch any errors. In the catch block,
log the error and return an appropriate error response (e.g., status 500 with an
error message) to the client to handle failures gracefully.
* feat: eid wallet basic ui for verification * chore: evault provisioning * feat: working wallet with provisioning * feat: restrict people on dupes * 📝 Add docstrings to `feat/evault-provisioning-via-phone` (#189) Docstrings generation was requested by @coodos. * #188 (comment) The following files were modified: * `infrastructure/eid-wallet/src/lib/utils/capitalize.ts` * `infrastructure/evault-provisioner/src/utils/hmac.ts` Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* initial commit * chore: add w3id readme (#3) * chore: add w3id readme * chore: bold text * chore: better formatting * docs: add w3id details * chore: format * chore: add links * fix: id spec considerations addressal (#8) * fix: id spec considerations addressal * fix: identity -> indentifier * chore: expand on trust list based recovery * chore: expand on AKA --------- Co-authored-by: Merul Dhiman <[email protected]> * Docs/eid wallet (#10) * chore: add eid-wallet folder * chore: add eid wallet docs * feat: add (#9) * feat(w3id): basic setup (#11) * feat(w3id): basic setup * fix(root): add infrastructure workspaces * update: lock file * feat(eidw): setup tauri (#40) * Feat/setup daisyui (#46) * feat: setup-daisyui * fix: index file * feat: colors added * feat: Archivo font added * fix: postcss added * fix: +layout.svelte file added * fix: packages * fix: fully migrating to tailwind v4 * feat: add Archivo font * feat: add danger colors * feat: twmerge and clsx added * feat: shadcn function added --------- Co-authored-by: Bekiboo <[email protected]> Co-authored-by: Julien <[email protected]> * feat: add storybook (#45) * feat: add storybook * update: lockfile * feat: created connection button (#48) * created connection button * added restprops to parent class * added onClick btn and storybook * fix: make font work in storybook (#54) * Feat/header (#55) * feat: add icons lib * fix: make font work in storybook * feat: Header * feat: runtime global added, icon library created, icons added, type file added * feat: header props added * fix: remove icons and type file as we are using lib for icons * fix: heading style * fix: color and icons, git merge branch 51, 54 * fix: color * fix: header-styling * fix: classes * chore: handlers added * chore: handlers added * fix: added heading --------- Co-authored-by: Soham Jaiswal <[email protected]> * Alternative w3id diagram (#52) * Feat/cupertino pane (#49) * feat: Drawer * feat: Drawer and added a function for clickoutside in utils * fix: classes * fix: drawer button position * fix: style and clickoutside * fix: pane height * fix: border-radius * fix: drawer as bulletin * fix: styling * fix: component with inbuilt features * fix: remove redundant code * fix: remove redundant code * fix: cancel button * fix: css in storybook * fix: position * fix: height of pane * fix: remove redundant code * feat: add button action component (#47) * feat: add button action component * fix: add correct weights to Archivo fontt * feat: add base button * fix: set prop classes last * feat: improve loading state * chore: cleanup * feat: add button action component * fix: add correct weights to Archivo fontt * feat: add base button * fix: set prop classes last * feat: improve loading state * chore: cleanup * chore: add documentation * fix: configure Storybook * chore: storybook gunk removal * feat: enhance ButtonAction component with type prop and better error handling --------- Co-authored-by: JulienAuvo <[email protected]> * Feat/splash screen (#63) * feat: SplashScreen * fix: remove redundant code * fix: as per given suggestion * fix: font-size * fix: logo * feat: input-pin (#56) * feat: input-pin * fix: styling as per our design * fix: added small variant * fix: hide pin on select * fix: gap between pins * fix: color of focus state * fix: removed legacy code and also fix some css to tailwind css * fix: css * fix: optional props * feat: added color variants * Feat/improve button component (#60) * feat: add white variant * feat: add small variant * chore: update doc and story for button * chore: rename cb into callback * update: improve small size * update: modify loading style * fix: return getAbsolutePath function to storybook (#58) Co-authored-by: Bekiboo <[email protected]> * feat: add selector component (#59) * feat: add selector component * feat: improve selector + add flag-icon lib * feat: improve selector + doc * feat: add utility function to get language with country name * feat: test page for language selectors * chore: add Selector Story * chore: clean test page * fix: types * fix: normalize custom tailwind colors (#71) * feat: workflows (#64) * feat: workflows * fix: node version * fix: use pnpm 10 * fix: check message * Fix/codebase linting (#73) * fix: Check Lint / lint * fix: Check Lint / lint * fix: Check Lint / lint * fix: Check Lint / lint * fix: Check Code / lint * fix: Check Format / lint * fix: Check Code / lint * fix: Check Format / lint * fix: Check Code / lint * fix: Check Format / lint * fix: Check Code / lint * fix: Check Code / lint * fix: Check Format / lint * fix: unknown property warning * fix: unknown property warning * chore: improve args type * settings nav button :) (#75) * setting bav button all done :) * lint fixski * added component to index.ts * Feat/#32 identity card fragment (#74) * identity card * identity card * lint fixski * lint fixski * lint fixski * fixed the font weight * added component to index.ts * changed span to buttton * feat: add icon button component (#68) * feat: add icon button component * feat: finish up buttonIcon + stories * fix: update with new color naming * feat: polish button icon (and button action too) * chore: format lint * chore: sort imports * chore: format, not sure why * Feat/onboarding flow (#67) * feat: onboarding-page * fix: line height and added handlers * fix: button variant * fix: text-decoration * fix: subtext * fix: underline * fix: padding and button spacing * fix: according to design update * feat: Drawer * feat: verify-pae * fix: verify-page styling * feat: drawer for both confirm pin and add bio metrics added * feat: modal added in fragments * fix: icons and flow * feat: Identifier Card * fix: copy to clipboard * feat: e-passport page * fix: error state * fix: colors * fix: lint error * fix: lint * feat: Typography * fix: typograpy * fix: as per given suggestion * fix: font-sizing * fix: identity card implementation * fix: spacing * fix: padding * fix: padding and spacing * fix: splashscreen * fix: error state * fix: styling to avoid * fix:typo * Fix/remove daisyui (#82) * refactoring: remove DaisyUI + refactor some tailwind classes and logic * refactoring: remove DaisyUI + refactor some tailwind classes and logic * feat: add Button.Nav (#77) * feat: add Button.Nav * chore: format * chore: sort imports * update: remove unused snippet and add missing props * feat: stick to fragment definition * update: documentation * fix: stories * chore: sort imports * Feat/splashscreen animation (#81) * feat: add animation to splashScreen * feat: implement data loading logic with splash screen delay * chore: sort import * update: use ButtonIcon is IdentityCard (#78) * update: use ButtonIcon is IdentityCard * feat: refactor ButtonIcon to be used anywhere in the app * chore: format indent * chore: remove useless change * feat: setup safe area (#80) * feat: setup safe area * chore: simplify implementation * chore: format * Feat/uuidv5 generation (#61) * feat: setup uuidv5 * chore: add test for deterministic UUID * feat: add Hero fragment (#88) * feat: add Hero fragment * chore: sort imports + add doc * feat: add storage specification abstract class (#92) * feat: add storage specification abstract class * chore: format and ignore lint * chore: change format checker on w3id * feat: settings-flow (#86) * feat: settings-flow * feat: settings and language page * feat : history page * feat: change pin page * fix: height of selector * fix: pin change page * fix: size of input pin * fix: spacing of pins * feat: AppNav fragment * fix: height of page * fix: padding * fix: remove redundant code * feat: privacy page * chore: add doc * fix: error state * feat: remove redundant code * chore: used app nav component --------- Co-authored-by: JulienAuvo <[email protected]> * feat: AppNav fragment (#90) * feat: AppNav fragment * chore: add doc * feat: Main page flow (#93) * feat: create root page + layout * feat: complete main page flow beta * chore: fix ts block * chore: sort imports * feat: integrate-flows (#94) * feat: intigrate-flows * fix: spacing in e-passport page * fix: page connectivity * feat: app page transitions * fix: z index * fix: pages * fix: view transition effect on splashscreen * fix: drawer pill and cancel button removed * fix: share button removed when onboarding * fix: remove share and view button when on onboarding flow * fix: remove view button * fix: ci checks * fix: transitions * fix: transititon according to direction * fix: lint error * fix: loop holes * Feat/w3id log generation (#98) * chore: create basic log generation mechanism * chore: add hashing utility function * chore: rotation event * feat: genesis entry * feat: generalize hash function * feat: append entry * chore: basic tests * chore: add tests for rotation * feat: add malform throws * chore: add the right errors * chore: fix CI stuff * chore: add missing file * chore: fix event type enum * chore: format * feat: add proper error * chore: format * chore: remove eventtypes enum * chore: add new error for bad options * chore: add options tests * feat: add codec tests * fix: err handling && jsdoc * fix: run format * fix: remove unused import * fix: improve default error messages * fix: move redundant logic to function * fix: run format * fix: type shadow * fix: useless conversion/cast * fix: run format --------- Co-authored-by: Soham Jaiswal <[email protected]> * Feat/core id creation logic (#99) * feat: create w3id builder * fix: w3id builder * feat: add global config var for w3id * chore: add docs * chore: change rand to crng * chore: add ts type again * chore: fix lint and format * chore: add w3id tests github workflow * Feat/evault core (#100) * feat: migrate neo4j * chore: envelope logic works * chore: envelope logic works * feat: parsed envelopes search * feat: generics * feat: protocol * feat: jwt sigs in w3id * chore: stuff works * chore: tests for evault core * chore: format * chore: fix test * Feat/docker compose and docs (#101) * chore: stash dockerfile progress * fix: getEnvelopesByOntology thing * chore: fix tests * Update infrastructure/evault-core/src/protocol/vault-access-guard.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * chore: remove unused import * chore: remove package * chore: fix pnpm lock * chore: fix workflow * chore: fix port in dockerfile --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Feat/registry and evault provisioning (#106) * feat: evault provisioning * chore: fianlly fixed provisioner * feat: add logic for metadata in consul * feat: registry * chore: format * Feat/watchers logs (#114) * feat: alloc according to entropy and namespace * chore: move exports * chore: docs * feat: `whois` endpoint * feat: watcher endpoints * chore: fix format and lint * chore: fix tests * feat: web3 adapter (#115) * feat: tauri plugins setup (#97) * feat: tauri plugins setup * fix: add editorconfig * fix: add missing biome json * fix: run formatter * feat: biometry homework * feat: add pin set logic * feat: add biometric enabling logic * fix: sec controller qol * feat: stub user controller * fix: run format && lint * fix: sort imports * fix: import statement sort * feat: user controller * feat: pin flow * feat: biometrics unavailable * fix: pin input not working * feat: make checks pass * fix: scan works * fix: actions * feat: format on save * fix: coderabbit suggestions * chore: run format lint check * fix: scan on decline too * feat: documentation links (#117) * feat: bad namespace test (#116) * fix: layouts (#119) * fix: layouts * fix: Onboarding page scroll fixed * fix: page layout and prevent from scroll in all devices * fix: pages layout * chore: try to fix emulator * fix: units * fix: safezones for ios * fix: styling --------- Co-authored-by: Soham Jaiswal <[email protected]> * feat: setup-metagram (#121) * feat: setup-metagram * chore: tailwind css worked * feat: fonts added * feat: typography * fix: removed stories and fixed setup for icons lib * feat: icons and story file * fix: type of args in story * fix: lint errors * feat: colors added * feat: Button * fix: format and lint * fix: colors * fix: spinner * fix: code rebbit suggestions * fix: code rebbit suggestions * fix: paraglide removed * fix: lock file * feat: added user avatar. (#130) * feat: Button (#129) * feat: Button * fix: colors of variants * feat: Input (#131) * feat: Input * feat: styling added * fix: styling * fix: styling * fix: added a new story * fix: focus states * fix: input states * Feat/settings navigation button (#140) * feat: settings-navigation-button * fix: handler added * chore: another variant added * fix: as per given suggestion * feat: BottomNav (#132) * feat: BottomNav * fix: icons * feat: profile icons created * feat: handler added * feat: handler added * fix: correct tags * fix: as per given suggestion, bottomnav moved to fragments and also implemented on page * fix: handler * chore: routes added * feat: app transitions added * fix: direction of transition * fix: transition css * fix: directionable transition * fix: used button instead of label, and used page from state * feat: added post fragment. (#137) * feat: FileInput (#150) * feat: FileInput * fix: added icon * feat: cancel upload * fix: remove redundant code * fix: usage docs added and as per requirements ' * fix: moved to framents * feat: Toggle Switch (#143) * feat: Toggle Switch * feat: Toggle Switch * fix: as per our design * fix: as per our design * feat: Label (#146) * feat: Select (#148) * feat: Select * fix: as per our design * fix: code format and as per svelte 5 * fix: font-size * fix: font-size * fix: icon * feat: message-input (#144) * feat: message-input * fix: classes merge and a files as a prop * feat: variant added * feat: icon replaced * fix: as per code rabbit suggestions * fix: icon * fix: input file button * fix: as per suggestion * fix: classes * fix: no need of error and disabled classes * fix: input * feat: invalid inputs * feat: add number input storybook --------- Co-authored-by: Soham Jaiswal <[email protected]> * feat:Drawer (#152) * feat:Drawer * feat: Drawer with clickoutside * fix: settings * Feat/metagram header (#133) * feat: added metagram header primary linear gradient. * feat: added flash icon. * feat: added secondary state of header. * feat: added secondary state of header with menu. * chore: cleaned some code. * docs: updated component docs. --------- Co-authored-by: SoSweetHam <[email protected]> * Feat/metagram message (#135) * feat: added metagram message component. * feat: added both states of message component. * docs: added usage docs. * chore: exposed component from ui. * fix: component -> fragement --------- Co-authored-by: SoSweetHam <[email protected]> * feat: modal (#154) * fix: styling of modal * fix: modal props * fix: conflicting styles * fix: styles of drawer * fix: hide scrollbar in drawer * fix: padding * fix: used native method for dismissing of drawer * feat: Context-Menu (#156) * feat: Context-Menu * fix: name of component * fix: as per suggestion * fix: action menu position * fix: class * feat: responsive-setup (#157) * feat: responsive-setup * fix: background color * fix: added font fmaily * feat: responsive setup for mobile and desktop (#159) * feat: responsive setup for mobile and desktop * fix: width of sidebar and rightaside * fix: responsive layout * feat: SideBar * fix: added some finishing touches to sidebar and button * fix: prevent pages transition on desktop * fix: icon center * feat: settings page and icon added * feat/layout-enhancement (#168) * feat/infinite-scroll (#170) * feat/infinite-scroll * fix: aspect ratio of post * fix: bottom nav background * settings page (#169) * settings page layout done * settings page layout done * formt fix * format fix * format fix * routing for settings page fixed * settings page buttons * merge conflict * settings page tertiary pages * settings pages all done * settings pages unnecessary page deleted * requested changes done * requested changes done * Feat/comments pane (#171) * feat/comments-pane * fix: overflow and drawer swipe * feat: Comment fragment * fix: comments added * fix: comment fragment * feat: Comments reply * fix: message input position * fix: post type shifted to types file * fix: one level deep only * fix: drawer should only be render on mobile * fix: comments on layout page * fix: format * feat: messages (#174) * feat: messages * feat: ChatMessae * feat: messages by id * fix: messages page * fix: icon name * fix: hide bottom nav for chat * fix: header * fix: message bubble * fix: message bubble * fix: message bubble * fix: as per suggestion * fix: messaging * chore: change from nomad to k8s (#179) * chore: change from nomad to k8s * Update infrastructure/eid-wallet/src/routes/+layout.svelte Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * feat: uri extraction * feat: regitry stuff * feat: registry using local db * 📝 Add docstrings to `feat/switch-to-k8s` (#181) Docstrings generation was requested by @coodos. * #179 (comment) The following files were modified: * `infrastructure/evault-provisioner/src/templates/evault.nomad.ts` Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * chore: format --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: make scan qr page work again (#185) * feat: Discover Page (#180) * refactor/Post (#186) * refactor/Post * fix: format and lint * fix: added dots for gallery * fix: added dots for gallery * fix: added dots for gallery * fix: plural name * feat: splash-screen (#187) * Feat/evault provisioning via phone (#188) * feat: eid wallet basic ui for verification * chore: evault provisioning * feat: working wallet with provisioning * feat: restrict people on dupes * 📝 Add docstrings to `feat/evault-provisioning-via-phone` (#189) Docstrings generation was requested by @coodos. * #188 (comment) The following files were modified: * `infrastructure/eid-wallet/src/lib/utils/capitalize.ts` * `infrastructure/evault-provisioner/src/utils/hmac.ts` Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * feat: added uploaded post view component. (#182) * feat: added uploaded post view component. * fix: fixed the outline and color. * fix: moved function to external definition. * fix: fixed the restProps. * profile page (#178) * basic layout for profile page * fixed alt text * merge conflict * profile page for other users implemented * fix: profile pages and logics * fixed all the pages of profile * fixed all the pages of profile * fix: format --------- Co-authored-by: gourav <[email protected]> * Feat/radio input (#176) * feat: added a radio button custom * docs: added name option in docs. * chore: cleaned the unnecessary classes and variables for input type radio. * fix: moved input radio to its own component. * fix: keydown events added. * feat: added settings tile component. (#184) * feat: added settings tile component. * chore: fixed the naming convention * chore: renamed callback to onclick * fix: fixed the use of restProps * fix: fixed the unnecessary onclick expose. * fix: fixed the join function params. * Feat/textarea (#194) * chore: removed redundant radio * feat: added textarea. * fix: tabindex * fix: removed type inconsitency. * Feat/mobile upload flow (#193) * fix: header logic in secondary * fix: fixed the text in header in post * feat: trying some hack to get file image input. * feat: added image input on clicking the post bottom nav * chore: got rid of non-required code. * feat: added the logic to get the images from user on clicking post tab. * feat: added store. * feat: added correct conversion of files. * feat: added the correct display of image when uploading. * feat: added settings tile to the post page and fixed the settingsTile component type of currentStatus * feat: added hte correct header for the audience page. * fix: fixed the page transition not happening to audience page. * feat: added audience setting * feat: added store to audience. * chore: removed console log * feat: added post button. * feat: correct button placement * fix: horizontal scroll * fix: positioning of the post button. * fix: protecting post route when no image is selected. * fix: improved type saftey * feat: added memory helper function * feat: added memory cleanup. * Feat/social media platforms (#195) * chore: this part works now wooohooo * chore: stash progress * chore: stash progress * chore: init message data models * feat: different socials * chore: blabsy ready for redesign * Feat/social media platforms (#196) * chore: this part works now wooohooo * chore: stash progress * chore: stash progress * chore: init message data models * feat: different socials * chore: blabsy ready for redesign * chore: add other socials * Feat/blabsy add clone (#198) * chore: clone twitter * feat: custom auth with firebase using w3ds * chore: add chat * feat: chat works with sync * feat: twittex * feat: global schemas * feat: blabsy adapter * refactor: shift some text messages to work on blabsy (#199) * chore: stash progress * chore: stash adapters * chore: stash working extractor * feat: adapter working properly for translating to global with globalIDs * feat: adapter toGlobal pristine * chore: stash * feat: adapter working * chore: stash until global translation from pictique * feat: bi-directional sync prestino * feat: bidir adapters * chore: login redir * chore: swap out for sqlite3 * chore: swap out for sqlite3 * chore: server conf * feat: messages one way * feat: ready to deploy * feat: ready to deploy * chore: auth thing pictique * chore: set adapter to node * chore: fix auth token thingy * chore: auth thing * chore: fix auth token thingy * chore: port for blabsy * feat: provision stuff * feat: provision * feat: provision * feat: provision * chore: fix sync * feat: temporary id thing * chore: android * chore: fix mapper sync * chore: fallback * feat: add error handling on stores * feat: fix issue with posts * chore: fix retry loop * Fix/author details (#229) * fix: author-details * fix: owner-details * fix: author avatar * fix: auth user avatar * fix: error handling * fix: author image in bottom nav --------- Co-authored-by: Merul Dhiman <[email protected]> * Fix/change name (#228) * fix: corrected the name to blabsy * fix: extra shit comming. * fix: fixed the alignment of the display in more to look more like current twitter. * fix: avatars (#226) * fix: avatars * fix: avatar in follow request page * fix: images uploaded shown in user profile * fix: button size * fix: avatar --------- Co-authored-by: Merul Dhiman <[email protected]> * chore: temp fix sync * chore: stash progress * Fix/post context menu (#231) * fix: post-context-menu * fix: user id with post * fix: removed redundant code * fix: images * fix: profile data * fix: profile data * fix: image cover * fix: logout * Fix/wallet text (#234) * changed text as per the request and fixed styling on pages with useless scroll * added settings button in main page which went missing somehow * fix: consistent padding * chore: change tags * feat: change icon * feat: webhook dynamic registry * feat: make camera permission work properlyh * chore: removed all locking mechanism thing from platforms * feat: synchronization works perfectly * feat: fixed everything up * feat: changes * chore: stats fix * chore: fix pictique visual issues * chore: fix cosmetic name issue * feat: fix sync issue * chore: fix logical issue here * chore: add qrcode ename * feat: add packages (#235) * feat: add packages * feat: add sample funcs + docs * fixed the filled color on like icon for liked post (#239) * feat: fake passport name * feat: double confirmation * chore: fix pictique login issue * fix: make no user case redir to login * fix: issues with wallet --------- Co-authored-by: Soham Jaiswal <[email protected]> Co-authored-by: SoSweetHam <[email protected]> Co-authored-by: Gourav Saini <[email protected]> Co-authored-by: Bekiboo <[email protected]> Co-authored-by: Julien <[email protected]> Co-authored-by: Ananya Rana <[email protected]> Co-authored-by: Sergey <[email protected]> Co-authored-by: Julien Connault <[email protected]> Co-authored-by: Ananya Rana <[email protected]> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Sahil Garg <[email protected]> Co-authored-by: Sahil Garg <[email protected]>
Description of change
Issue Number
Type of change
How the change has been tested
Change checklist
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Chores
Tests