update user schema, webauthn bug fix

This commit is contained in:
2025-02-24 16:56:25 +05:30
parent dee35bec5b
commit fef560127a
8 changed files with 22 additions and 6 deletions

View File

@@ -21,6 +21,7 @@
"@fastify/oauth2": "^8.1.0", "@fastify/oauth2": "^8.1.0",
"@paralleldrive/cuid2": "^2.2.2", "@paralleldrive/cuid2": "^2.2.2",
"@simplewebauthn/server": "^13.1.1", "@simplewebauthn/server": "^13.1.1",
"@types/qs": "^6.9.18",
"axios": "^1.7.9", "axios": "^1.7.9",
"bcryptjs": "^3.0.0", "bcryptjs": "^3.0.0",
"fastify": "^5.2.0", "fastify": "^5.2.0",

8
pnpm-lock.yaml generated
View File

@@ -32,6 +32,9 @@ importers:
'@simplewebauthn/server': '@simplewebauthn/server':
specifier: ^13.1.1 specifier: ^13.1.1
version: 13.1.1 version: 13.1.1
'@types/qs':
specifier: ^6.9.18
version: 6.9.18
axios: axios:
specifier: ^1.7.9 specifier: ^1.7.9
version: 1.7.9 version: 1.7.9
@@ -570,6 +573,9 @@ packages:
'@types/node@22.10.2': '@types/node@22.10.2':
resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==}
'@types/qs@6.9.18':
resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==}
'@types/webidl-conversions@7.0.3': '@types/webidl-conversions@7.0.3':
resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==} resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==}
@@ -2195,6 +2201,8 @@ snapshots:
dependencies: dependencies:
undici-types: 6.20.0 undici-types: 6.20.0
'@types/qs@6.9.18': {}
'@types/webidl-conversions@7.0.3': {} '@types/webidl-conversions@7.0.3': {}
'@types/whatwg-url@11.0.5': '@types/whatwg-url@11.0.5':

View File

@@ -17,7 +17,7 @@ export async function mailProxyRoutes(fastify: FastifyInstance) {
const input = req.body as ProxyRequest; const input = req.body as ProxyRequest;
try { try {
const tokens = await getOutlookTokens(input.email); const tokens = await getOutlookTokens(input.id);
if (!tokens) return res.code(404).send({ error: "resource not found" }); if (!tokens) return res.code(404).send({ error: "resource not found" });
const result = await axios({ const result = await axios({

View File

@@ -18,7 +18,7 @@ export const mailModel = mongoose.model(
); );
const proxyRequest = z.object({ const proxyRequest = z.object({
email: z.string().email(), id: z.string(),
url: z.string(), url: z.string(),
method: z.enum(["GET", "POST", "PATCH", "DELETE"]), method: z.enum(["GET", "POST", "PATCH", "DELETE"]),
body: z.any(), body: z.any(),

View File

@@ -28,7 +28,7 @@ const userSchema = new mongoose.Schema({
type: String, type: String,
required: true, required: true,
}, },
passKeys: [], passKeys: [new mongoose.Schema({}, { _id: false, strict: false })],
challenge: new mongoose.Schema( challenge: new mongoose.Schema(
{ {
value: String, value: String,

View File

@@ -73,7 +73,7 @@ export async function getUploadUrlMultiPart(key: string, fileSize: number) {
export async function completeMultiPartUpload( export async function completeMultiPartUpload(
key: string, key: string,
uploadId: string, uploadId: string,
parts: { ETag: string; PartNumber: number }[] parts: { ETag?: string; PartNumber?: number }[]
) { ) {
const command = new CompleteMultipartUploadCommand({ const command = new CompleteMultipartUploadCommand({
Key: key, Key: key,

View File

@@ -51,8 +51,10 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
userName: email, userName: email,
attestationType: "none", attestationType: "none",
excludeCredentials: userInDB.passKeys.map((cred) => ({ excludeCredentials: userInDB.passKeys.map((cred) => ({
// @ts-ignore
id: cred.credentialID, id: cred.credentialID,
type: "public-key", type: "public-key",
// @ts-ignore
transports: cred.transports, transports: cred.transports,
})), })),
}); });
@@ -96,7 +98,7 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
properties: { properties: {
email: { type: "string" }, email: { type: "string" },
code: { type: "string" }, code: { type: "string" },
attestationResponse: { type: "object" }, attestationResponse: { type: "object", additionalProperties: true },
}, },
}, },
}, },
@@ -174,8 +176,10 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
await generateAuthenticationOptions({ await generateAuthenticationOptions({
rpID, rpID,
allowCredentials: userInDB.passKeys.map((cred) => ({ allowCredentials: userInDB.passKeys.map((cred) => ({
// @ts-ignore
id: cred.credentialID, id: cred.credentialID,
type: "public-key", type: "public-key",
// @ts-ignore
transports: cred.transports, transports: cred.transports,
})), })),
userVerification: "preferred", userVerification: "preferred",
@@ -218,6 +222,7 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
try { try {
const credential = userInDB.passKeys.find( const credential = userInDB.passKeys.find(
// @ts-ignore
(cred) => cred.credentialID === assertionResponse.id (cred) => cred.credentialID === assertionResponse.id
); );
@@ -230,12 +235,14 @@ export async function webAuthnRoutes(fastify: FastifyInstance) {
expectedChallenge: userInDB.challenge.value as string, expectedChallenge: userInDB.challenge.value as string,
expectedRPID: rpID, expectedRPID: rpID,
expectedOrigin: origin, expectedOrigin: origin,
// @ts-ignore
credential: credential, credential: credential,
}); });
if (!verification.verified) if (!verification.verified)
return res.code(400).send({ error: "Authentication failed" }); return res.code(400).send({ error: "Authentication failed" });
// @ts-ignore
credential.counter = verification.authenticationInfo.newCounter; credential.counter = verification.authenticationInfo.newCounter;
const newSession = await createSession( const newSession = await createSession(

View File

@@ -85,7 +85,7 @@
/* Type Checking */ /* Type Checking */
// "strict": true, /* Enable all strict type-checking options. */ // "strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
"strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */