{"version":3,"file":"_id_.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/auth/passkey/[id].ts"],"sourcesContent":["/**\n * PATCH/DELETE /_emdash/api/auth/passkey/[id]\n *\n * Rename or delete a passkey\n */\n\nimport type { APIRoute } from \"astro\";\n\nexport const prerender = false;\n\nimport { createKyselyAdapter } from \"@premium-cms/auth/adapters/kysely\";\n\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { passkeyRenameBody } from \"#api/schemas.js\";\n\ninterface PasskeyResponse {\n\tid: string;\n\tname: string | null;\n\tdeviceType: \"singleDevice\" | \"multiDevice\";\n\tbackedUp: boolean;\n\tcreatedAt: string;\n\tlastUsedAt: string;\n}\n\n/**\n * PATCH - Rename a passkey\n */\nexport const PATCH: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\t// Require authentication\n\tif (!user) {\n\t\treturn apiError(\"NOT_AUTHENTICATED\", \"Not authenticated\", 401);\n\t}\n\n\tif (!id) {\n\t\treturn apiError(\"MISSING_PARAM\", \"Passkey ID is required\", 400);\n\t}\n\n\ttry {\n\t\tconst adapter = createKyselyAdapter(emdash.db);\n\n\t\t// Get the credential and verify ownership\n\t\tconst credential = await adapter.getCredentialById(id);\n\n\t\tif (!credential || credential.userId !== user.id) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Passkey not found\", 404);\n\t\t}\n\n\t\t// Parse request body\n\t\tconst body = await parseBody(request, passkeyRenameBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// Update the name\n\t\tconst trimmedName = body.name.trim() || null;\n\t\tawait adapter.updateCredentialName(id, trimmedName);\n\n\t\t// Return updated passkey info\n\t\tconst passkey: PasskeyResponse = {\n\t\t\tid: credential.id,\n\t\t\tname: trimmedName,\n\t\t\tdeviceType: credential.deviceType,\n\t\t\tbackedUp: credential.backedUp,\n\t\t\tcreatedAt: credential.createdAt.toISOString(),\n\t\t\tlastUsedAt: credential.lastUsedAt.toISOString(),\n\t\t};\n\n\t\treturn apiSuccess({ passkey });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to rename passkey\", \"PASSKEY_RENAME_ERROR\");\n\t}\n};\n\n/**\n * DELETE - Remove a passkey\n */\nexport const DELETE: APIRoute = async ({ params, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { id } = params;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\t// Require authentication\n\tif (!user) {\n\t\treturn apiError(\"NOT_AUTHENTICATED\", \"Not authenticated\", 401);\n\t}\n\n\tif (!id) {\n\t\treturn apiError(\"MISSING_PARAM\", \"Passkey ID is required\", 400);\n\t}\n\n\ttry {\n\t\tconst adapter = createKyselyAdapter(emdash.db);\n\n\t\t// Get the credential and verify ownership\n\t\tconst credential = await adapter.getCredentialById(id);\n\n\t\tif (!credential || credential.userId !== user.id) {\n\t\t\treturn apiError(\"NOT_FOUND\", \"Passkey not found\", 404);\n\t\t}\n\n\t\t// Check that this isn't the last passkey\n\t\tconst count = await adapter.countCredentialsByUserId(user.id);\n\n\t\tif (count <= 1) {\n\t\t\treturn apiError(\"LAST_PASSKEY\", \"Cannot remove your last passkey\", 400);\n\t\t}\n\n\t\t// Delete the passkey\n\t\tawait adapter.deleteCredential(id);\n\n\t\treturn apiSuccess({ success: true });\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to delete passkey\", \"PASSKEY_DELETE_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;;;;AAQA,MAAa,YAAY;;;;AAoBzB,MAAa,QAAkB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACrE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,OAAO;AAEf,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAIpE,KAAI,CAAC,KACJ,QAAO,SAAS,qBAAqB,qBAAqB,IAAI;AAG/D,KAAI,CAAC,GACJ,QAAO,SAAS,iBAAiB,0BAA0B,IAAI;AAGhE,KAAI;EACH,MAAM,UAAU,oBAAoB,OAAO,GAAG;EAG9C,MAAM,aAAa,MAAM,QAAQ,kBAAkB,GAAG;AAEtD,MAAI,CAAC,cAAc,WAAW,WAAW,KAAK,GAC7C,QAAO,SAAS,aAAa,qBAAqB,IAAI;EAIvD,MAAM,OAAO,MAAM,UAAU,SAAS,kBAAkB;AACxD,MAAI,aAAa,KAAK,CAAE,QAAO;EAG/B,MAAM,cAAc,KAAK,KAAK,MAAM,IAAI;AACxC,QAAM,QAAQ,qBAAqB,IAAI,YAAY;AAYnD,SAAO,WAAW,EAAE,SATa;GAChC,IAAI,WAAW;GACf,MAAM;GACN,YAAY,WAAW;GACvB,UAAU,WAAW;GACrB,WAAW,WAAW,UAAU,aAAa;GAC7C,YAAY,WAAW,WAAW,aAAa;GAC/C,EAE4B,CAAC;UACtB,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB;;;;;;AAO/E,MAAa,SAAmB,OAAO,EAAE,QAAQ,aAAa;CAC7D,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,OAAO;AAEf,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;AAIpE,KAAI,CAAC,KACJ,QAAO,SAAS,qBAAqB,qBAAqB,IAAI;AAG/D,KAAI,CAAC,GACJ,QAAO,SAAS,iBAAiB,0BAA0B,IAAI;AAGhE,KAAI;EACH,MAAM,UAAU,oBAAoB,OAAO,GAAG;EAG9C,MAAM,aAAa,MAAM,QAAQ,kBAAkB,GAAG;AAEtD,MAAI,CAAC,cAAc,WAAW,WAAW,KAAK,GAC7C,QAAO,SAAS,aAAa,qBAAqB,IAAI;AAMvD,MAFc,MAAM,QAAQ,yBAAyB,KAAK,GAAG,IAEhD,EACZ,QAAO,SAAS,gBAAgB,mCAAmC,IAAI;AAIxE,QAAM,QAAQ,iBAAiB,GAAG;AAElC,SAAO,WAAW,EAAE,SAAS,MAAM,CAAC;UAC5B,OAAO;AACf,SAAO,YAAY,OAAO,4BAA4B,uBAAuB"}