diff --git a/apps/api-server/src/middleware/auth.ts b/apps/api-server/src/middleware/auth.ts index 71e3647..7b8b7ce 100644 --- a/apps/api-server/src/middleware/auth.ts +++ b/apps/api-server/src/middleware/auth.ts @@ -113,14 +113,14 @@ export const createAuthMiddleware = () => { const sessionInfo: Session = session ? { - id: Number(session.id), + id: session.id, trustedMode: session.trusted_mode, createdAt: session.created_at, } : { // For API token auth, create a synthetic session object // We know apiToken exists because userId came from it - id: 0, + id: "0", trustedMode: true, createdAt: apiToken?.created_at ?? new Date(), }; diff --git a/apps/api-server/src/procedures/auth/login-password.ts b/apps/api-server/src/procedures/auth/login-password.ts index a59991b..53dd811 100644 --- a/apps/api-server/src/procedures/auth/login-password.ts +++ b/apps/api-server/src/procedures/auth/login-password.ts @@ -110,7 +110,11 @@ export const loginPassword = os.auth.loginPassword.handler( // Password is valid - check if device is trusted // If no device fingerprint, treat as untrusted const deviceTrusted = result.device_fingerprint - ? await isDeviceTrusted(context.db, result.user_id, result.device_fingerprint) + ? await isDeviceTrusted( + context.db, + result.user_id, + result.device_fingerprint, + ) : false; if (deviceTrusted) { diff --git a/apps/api-server/src/procedures/auth/logout.ts b/apps/api-server/src/procedures/auth/logout.ts index fd37140..1fa5762 100644 --- a/apps/api-server/src/procedures/auth/logout.ts +++ b/apps/api-server/src/procedures/auth/logout.ts @@ -14,13 +14,13 @@ import { authMiddleware, os } from "../base.js"; export const logout = os.auth.logout .use(authMiddleware) .handler(async ({ context }) => { - // Revoke the current session - await context.db - .updateTable("sessions") - .set({ revoked_at: new Date() }) - .where("id", "=", String(context.session.id)) - .execute(); + // Revoke the current session + await context.db + .updateTable("sessions") + .set({ revoked_at: new Date() }) + .where("id", "=", context.session.id) + .execute(); - // Clear the session cookie - deleteCookie(context.resHeaders, COOKIE_NAMES.SESSION_TOKEN); -}); + // Clear the session cookie + deleteCookie(context.resHeaders, COOKIE_NAMES.SESSION_TOKEN); + }); diff --git a/apps/api-server/src/procedures/auth/resend-verification.ts b/apps/api-server/src/procedures/auth/resend-verification.ts index 28ffe75..ad1b190 100644 --- a/apps/api-server/src/procedures/auth/resend-verification.ts +++ b/apps/api-server/src/procedures/auth/resend-verification.ts @@ -18,32 +18,32 @@ import { authMiddleware, os } from "../base.js"; export const resendVerificationEmail = os.auth.resendVerificationEmail .use(authMiddleware) .handler(async ({ context }) => { - // Check if email is already verified - if (context.user.emailVerifiedAt !== null) { - // Email already verified, return early - return; - } + // Check if email is already verified + if (context.user.emailVerifiedAt !== null) { + // Email already verified, return early + return; + } - // Delete any existing verification tokens for this user - await context.db - .deleteFrom("email_verifications") - .where("user_id", "=", context.user.id) - .execute(); + // Delete any existing verification tokens for this user + await context.db + .deleteFrom("email_verifications") + .where("user_id", "=", context.user.id) + .execute(); - // Generate new secure token - const token = generateSecureToken(); - const expiresAt = generateExpiry(TOKEN_DURATIONS.EMAIL_VERIFICATION); + // Generate new secure token + const token = generateSecureToken(); + const expiresAt = generateExpiry(TOKEN_DURATIONS.EMAIL_VERIFICATION); - // Create new verification record - await context.db - .insertInto("email_verifications") - .values({ - user_id: context.user.id, - token, - expires_at: expiresAt, - }) - .execute(); + // Create new verification record + await context.db + .insertInto("email_verifications") + .values({ + user_id: context.user.id, + token, + expires_at: expiresAt, + }) + .execute(); - // Send verification email (stubbed) - await sendVerificationEmail(context.user.email, token); -}); + // Send verification email (stubbed) + await sendVerificationEmail(context.user.email, token); + }); diff --git a/apps/api-server/src/procedures/auth/signup.ts b/apps/api-server/src/procedures/auth/signup.ts index cbfeabe..e821362 100644 --- a/apps/api-server/src/procedures/auth/signup.ts +++ b/apps/api-server/src/procedures/auth/signup.ts @@ -2,16 +2,15 @@ * Signup procedure - creates a new user account with email + password or passkey */ +import type { DB } from "@reviq/db-schema"; import type { PublicKeyCredentialCreationOptionsJSON, RegistrationResponseJSON, } from "@simplewebauthn/types"; import type { Kysely } from "kysely"; -import type { DB } from "@reviq/db-schema"; import type { RPInfo } from "../../utils/webauthn.js"; import { ORPCError } from "@orpc/server"; import { verifyRegistrationResponse } from "@simplewebauthn/server"; -import { os } from "../base.js"; import { COOKIE_NAMES, COOKIE_OPTIONS, @@ -24,6 +23,7 @@ import { getGeoInfo, getUserAgent } from "../../utils/geo.js"; import { hashPassword, validatePassword } from "../../utils/password.js"; import { createSession } from "../../utils/session.js"; import { getRPInfo, KNOWN_AAGUIDS } from "../../utils/webauthn.js"; +import { os } from "../base.js"; /** * Create user with password authentication @@ -231,7 +231,11 @@ export const signup = os.auth.signup.handler(async ({ input, context }) => { if (password) { userId = await signupWithPassword(context.db, email, password); } else if (passkeyInfo) { - const rpInfo = getRPInfo(context.origin, context.allowedOrigins, context.rpName); + const rpInfo = getRPInfo( + context.origin, + context.allowedOrigins, + context.rpName, + ); userId = await signupWithPasskey(context.db, email, passkeyInfo, rpInfo); } else { // Should never reach here due to schema validation diff --git a/apps/api-server/src/procedures/base.ts b/apps/api-server/src/procedures/base.ts index 06d3ed8..4f4f34d 100644 --- a/apps/api-server/src/procedures/base.ts +++ b/apps/api-server/src/procedures/base.ts @@ -111,13 +111,13 @@ export const authMiddleware = os.middleware(async ({ context, next }) => { const sessionInfo: Session = session ? { - id: Number(session.id), + id: session.id, trustedMode: session.trusted_mode, createdAt: session.created_at, } : { // For API token auth, create a synthetic session object - id: 0, + id: "0", trustedMode: true, createdAt: apiToken?.created_at ?? new Date(), }; @@ -133,69 +133,71 @@ export const authMiddleware = os.middleware(async ({ context, next }) => { /** * Login request middleware - validates login request token from cookie */ -export const loginRequestMiddleware = os.middleware(async ({ context, next }) => { - const { db, reqHeaders } = context; +export const loginRequestMiddleware = os.middleware( + async ({ context, next }) => { + const { db, reqHeaders } = context; - // Read login request token from cookie - const loginRequestToken = getCookie( - reqHeaders, - COOKIE_NAMES.LOGIN_REQUEST_TOKEN, - ); + // Read login request token from cookie + const loginRequestToken = getCookie( + reqHeaders, + COOKIE_NAMES.LOGIN_REQUEST_TOKEN, + ); - if (!loginRequestToken) { - throw new ORPCError("BAD_REQUEST", { - message: "No login request found", + if (!loginRequestToken) { + throw new ORPCError("BAD_REQUEST", { + message: "No login request found", + }); + } + + // Check if token is a valid login request ID (numeric) + const num = Number(loginRequestToken); + if (Number.isNaN(num) || !Number.isInteger(num) || num <= 0) { + throw new ORPCError("BAD_REQUEST", { + message: "Invalid login request", + }); + } + + const loginRequestId = loginRequestToken; + + // Fetch login request with user data + const result = await db + .selectFrom("login_requests") + .innerJoin("users", "users.id", "login_requests.user_id") + .select([ + "login_requests.id", + "login_requests.user_id", + "login_requests.expires_at", + "users.email", + "users.display_name", + "users.email_verified_at", + "users.is_superuser", + ]) + .where("login_requests.id", "=", loginRequestId) + .where("login_requests.expires_at", ">", new Date()) + .executeTakeFirst(); + + if (!result) { + throw new ORPCError("BAD_REQUEST", { + message: "Login request expired or not found", + }); + } + + const sessionUser: SessionUser = { + id: result.user_id, + email: result.email, + displayName: result.display_name, + emailVerifiedAt: result.email_verified_at, + isSuperuser: result.is_superuser, + }; + + return next({ + context: { + loginRequestId: Number(result.id), + user: sessionUser, + }, }); - } - - // Check if token is a valid login request ID (numeric) - const num = Number(loginRequestToken); - if (Number.isNaN(num) || !Number.isInteger(num) || num <= 0) { - throw new ORPCError("BAD_REQUEST", { - message: "Invalid login request", - }); - } - - const loginRequestId = loginRequestToken; - - // Fetch login request with user data - const result = await db - .selectFrom("login_requests") - .innerJoin("users", "users.id", "login_requests.user_id") - .select([ - "login_requests.id", - "login_requests.user_id", - "login_requests.expires_at", - "users.email", - "users.display_name", - "users.email_verified_at", - "users.is_superuser", - ]) - .where("login_requests.id", "=", loginRequestId) - .where("login_requests.expires_at", ">", new Date()) - .executeTakeFirst(); - - if (!result) { - throw new ORPCError("BAD_REQUEST", { - message: "Login request expired or not found", - }); - } - - const sessionUser: SessionUser = { - id: result.user_id, - email: result.email, - displayName: result.display_name, - emailVerifiedAt: result.email_verified_at, - isSuperuser: result.is_superuser, - }; - - return next({ - context: { - loginRequestId: Number(result.id), - user: sessionUser, - }, - }); -}); + }, +); /** * Superuser middleware - requires admin access (must be used after authMiddleware) diff --git a/apps/api-server/src/router.ts b/apps/api-server/src/router.ts index 72830aa..7743973 100644 --- a/apps/api-server/src/router.ts +++ b/apps/api-server/src/router.ts @@ -9,7 +9,11 @@ import { resendVerificationEmail as resendVerificationHandler } from "./procedur import { resetPassword as resetPasswordHandler } from "./procedures/auth/reset-password.js"; import { signup as signupHandler } from "./procedures/auth/signup.js"; import { verifyEmail as verifyEmailHandler } from "./procedures/auth/verify-email.js"; -import { authMiddleware, loginRequestMiddleware, os } from "./procedures/base.js"; +import { + authMiddleware, + loginRequestMiddleware, + os, +} from "./procedures/base.js"; import { createAuthenticationOptions as createAuthOptions, createRegistrationOptions as createRegOptions, @@ -39,7 +43,11 @@ const createRegistrationOptions = // For signup flow, we don't have a user yet // The user will be created when signup is called with the passkeyInfo - const rpInfo = getRPInfo(context.origin, context.allowedOrigins, context.rpName); + const rpInfo = getRPInfo( + context.origin, + context.allowedOrigins, + context.rpName, + ); const result = await createRegOptions(context.db, rpInfo, { email }); return result; @@ -51,14 +59,22 @@ const verifyRegistration = os.auth.webauthn.verifyRegistration .handler(async ({ input, context }) => { const { challengeId, response } = input; - const rpInfo = getRPInfo(context.origin, context.allowedOrigins, context.rpName); + const rpInfo = getRPInfo( + context.origin, + context.allowedOrigins, + context.rpName, + ); await verifyReg(context.db, rpInfo, context.user.id, challengeId, response); }); const createAuthenticationOptions = os.auth.webauthn.createAuthenticationOptions .use(loginRequestMiddleware) .handler(async ({ context }) => { - const rpInfo = getRPInfo(context.origin, context.allowedOrigins, context.rpName); + const rpInfo = getRPInfo( + context.origin, + context.allowedOrigins, + context.rpName, + ); const result = await createAuthOptions(context.db, rpInfo, context.user.id); return result; }); @@ -68,7 +84,11 @@ const verifyAuthentication = os.auth.webauthn.verifyAuthentication .handler(async ({ input, context }) => { const { challengeId, response } = input; - const rpInfo = getRPInfo(context.origin, context.allowedOrigins, context.rpName); + const rpInfo = getRPInfo( + context.origin, + context.allowedOrigins, + context.rpName, + ); const verified = await verifyAuth( context.db, rpInfo, @@ -89,13 +109,17 @@ const meGet = os.me.get.use(authMiddleware).handler(async () => { throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); }); -const setupProfile = os.me.setupProfile.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const setupProfile = os.me.setupProfile + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const updateProfile = os.me.updateProfile.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const updateProfile = os.me.updateProfile + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); const meDelete = os.me.delete.use(authMiddleware).handler(async () => { throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); @@ -105,7 +129,7 @@ const setPassword = os.me.setPassword.use(authMiddleware).handler(async () => { throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); }); -const listPasskeys = os.me.listPasskeys +const passkeysList = os.me.passkeys.list .use(authMiddleware) .handler(async ({ context }) => { const passkeys = await getUserPasskeys(context.db, context.user.id); @@ -118,22 +142,7 @@ const listPasskeys = os.me.listPasskeys })); }); -const createPasskey = os.me.createPasskey - .use(authMiddleware) - .handler(async ({ input, context }) => { - const { name: _name } = input; - - const rpInfo = getRPInfo(context.origin, context.allowedOrigins, context.rpName); - const result = await createRegOptions(context.db, rpInfo, { - id: context.user.id, - email: context.user.email, - displayName: context.user.displayName, - }); - - return result; - }); - -const renamePasskey = os.me.renamePasskey +const passkeysRename = os.me.passkeys.rename .use(authMiddleware) .handler(async ({ input, context }) => { const { passkeyId, name } = input; @@ -146,7 +155,7 @@ const renamePasskey = os.me.renamePasskey .execute(); }); -const deletePasskey = os.me.deletePasskey +const passkeysDelete = os.me.passkeys.delete .use(authMiddleware) .handler(async ({ input, context }) => { const { passkeyId } = input; @@ -177,33 +186,45 @@ const deletePasskey = os.me.deletePasskey .execute(); }); -const listSessions = os.me.listSessions.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const listSessions = os.me.listSessions + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const revokeSession = os.me.revokeSession.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const revokeSession = os.me.revokeSession + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const revokeAllSessions = os.me.revokeAllSessions.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const revokeAllSessions = os.me.revokeAllSessions + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const getDeviceInfo = os.me.getDeviceInfo.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const getDeviceInfo = os.me.getDeviceInfo + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); const trustDevice = os.me.trustDevice.use(authMiddleware).handler(async () => { throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); }); -const listTrustedDevices = os.me.listTrustedDevices.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const listTrustedDevices = os.me.listTrustedDevices + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const untrustDevice = os.me.untrustDevice.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const untrustDevice = os.me.untrustDevice + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); const revokeAllTrustedDevices = os.me.revokeAllTrustedDevices .use(authMiddleware) @@ -237,34 +258,48 @@ const orgsLeave = os.orgs.leave.use(authMiddleware).handler(async () => { }); // Orgs members procedures -const membersList = os.orgs.members.list.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const membersList = os.orgs.members.list + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const membersUpdateRole = os.orgs.members.updateRole.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const membersUpdateRole = os.orgs.members.updateRole + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const membersRemove = os.orgs.members.remove.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const membersRemove = os.orgs.members.remove + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); // Orgs invites procedures -const invitesList = os.orgs.invites.list.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const invitesList = os.orgs.invites.list + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const invitesCreate = os.orgs.invites.create.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const invitesCreate = os.orgs.invites.create + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const invitesCancel = os.orgs.invites.cancel.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const invitesCancel = os.orgs.invites.cancel + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const invitesAccept = os.orgs.invites.accept.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const invitesAccept = os.orgs.invites.accept + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); // Orgs sites procedures const sitesList = os.orgs.sites.list.use(authMiddleware).handler(async () => { @@ -272,63 +307,89 @@ const sitesList = os.orgs.sites.list.use(authMiddleware).handler(async () => { }); // Admin orgs procedures (require superuser - for now just auth, will add superuser middleware later) -const adminOrgsList = os.admin.orgs.list.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminOrgsList = os.admin.orgs.list + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); const adminOrgsGet = os.admin.orgs.get.use(authMiddleware).handler(async () => { throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); }); -const adminOrgsCreate = os.admin.orgs.create.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminOrgsCreate = os.admin.orgs.create + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const adminOrgsUpdate = os.admin.orgs.update.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminOrgsUpdate = os.admin.orgs.update + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const adminOrgsDelete = os.admin.orgs.delete.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminOrgsDelete = os.admin.orgs.delete + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const adminOrgsListSites = os.admin.orgs.listSites.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminOrgsListSites = os.admin.orgs.listSites + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const adminOrgsAddSite = os.admin.orgs.addSite.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminOrgsAddSite = os.admin.orgs.addSite + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const adminOrgsRemoveSite = os.admin.orgs.removeSite.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminOrgsRemoveSite = os.admin.orgs.removeSite + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); // Admin users procedures -const adminUsersList = os.admin.users.list.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminUsersList = os.admin.users.list + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const adminUsersGet = os.admin.users.get.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminUsersGet = os.admin.users.get + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const adminUsersCreate = os.admin.users.create.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminUsersCreate = os.admin.users.create + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const adminUsersUpdate = os.admin.users.update.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminUsersUpdate = os.admin.users.update + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); -const adminUsersConfirmEmail = os.admin.users.confirmEmail.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminUsersConfirmEmail = os.admin.users.confirmEmail + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); // Admin auth procedures -const adminAuthCompleteLogin = os.admin.auth.completeLogin.use(authMiddleware).handler(async () => { - throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); -}); +const adminAuthCompleteLogin = os.admin.auth.completeLogin + .use(authMiddleware) + .handler(async () => { + throw new ORPCError("NOT_IMPLEMENTED", { message: "Not implemented" }); + }); // Build the router export const router = os.router({ @@ -356,10 +417,11 @@ export const router = os.router({ updateProfile, delete: meDelete, setPassword, - listPasskeys, - createPasskey, - renamePasskey, - deletePasskey, + passkeys: { + list: passkeysList, + rename: passkeysRename, + delete: passkeysDelete, + }, listSessions, revokeSession, revokeAllSessions,