allow PATCH /account/:id with application/x-www-form-urlencoded, limit on codes

This commit is contained in:
May 2024-06-25 12:48:35 -07:00
parent 735878fe6a
commit c53a31c405
Signed by: split
GPG key ID: C325C61F0BF517C0
2 changed files with 27 additions and 8 deletions

View file

@ -4,12 +4,14 @@ import crypto from "node:crypto"
export type Intent = "verifyEmail" | "recoverAccount" | "identityProof"
export const Intents = {
verifyEmail: {},
verifyEmail: {
limit: 2
},
recoverAccount: {},
identityProof: {
codeGenerator: crypto.randomUUID
}
} as Record<Intent, {codeGenerator?: () => string}>
} as Record<Intent, {codeGenerator?: () => string, limit?: number}>
export function isIntent(intent: string): intent is Intent {
return intent in Intents
@ -73,3 +75,14 @@ export class Code {
return forUser === this.for
}
}
export function code(...params: ConstructorParameters<typeof Code>): { success: true, code: Code } | { success: false, error: string } {
const [intent, forUser] = params
const {limit = 100} = Intents[intent]
const {length: codeCount} = codes[intent].byUser.get(forUser) || [];
if (codeCount >= limit)
return { success: false, error: `Too many active codes for intent ${intent} (${limit})` }
else
return { success: true, code: new Code(...params) }
}

View file

@ -111,12 +111,12 @@ const validators: {
// send verification email
if (
(CodeMgr.codes.verifyEmail.byUser.get(target.id)?.length || 0) >= 2
)
return [429, "you have too many active codes"]
const tryCode = CodeMgr.code("verifyEmail", target.id, params.email)
let code = new CodeMgr.Code("verifyEmail", target.id, params.email)
if (!tryCode.success)
return [429, tryCode.error]
const { code } = tryCode
sendMail(
params.email,
@ -302,7 +302,13 @@ export default function (files: Files) {
router.patch(
"/:user",
scheme(UserUpdateScheme),
scheme(
UserUpdateScheme,
(c) =>
c.req.header("content-type") == "application/x-www-form-urlencoded"
? c.req.param()
: c.req.json()
),
assertAPI(
ctx =>
Object.keys(ctx.get("parsedScheme"))