diff --git a/.changeset/registration-ttl-is-a-number.md b/.changeset/registration-ttl-is-a-number.md new file mode 100644 index 0000000..0ec4852 --- /dev/null +++ b/.changeset/registration-ttl-is-a-number.md @@ -0,0 +1,14 @@ +--- +'seamless-auth-api': patch +--- + +Send the registration response's `ttl` as a number. + +It was the string `'300'`, the only `ttl` this API sends that was not a number. A caller sets its +registration cookie from it, and the Fastify adapter passes the value to a cookie library that +requires an integer, so registration failed there with `TypeError: option maxAge is invalid: 300`. +The Express adapter multiplies it into milliseconds, which coerces the string, so the same response +worked and the mismatch went unnoticed. + +Requires `@seamless-auth/types` 0.6.0, where `RegistrationSuccessSchema.ttl` becomes a number. +Response bodies are validated against that schema at runtime, so the two move together. diff --git a/openapi.json b/openapi.json index 8461913..a849e9b 100644 --- a/openapi.json +++ b/openapi.json @@ -1,6 +1,6 @@ { "openapi": "3.0.3", - "info": { "title": "Seamless Auth API", "version": "0.6.0" }, + "info": { "title": "Seamless Auth API", "version": "0.7.0" }, "components": { "schemas": {}, "parameters": {}, @@ -5415,7 +5415,7 @@ "message": { "type": "string" }, "sub": { "type": "string" }, "token": { "type": "string" }, - "ttl": { "type": "string" }, + "ttl": { "type": "number" }, "delivery": { "oneOf": [ { @@ -5455,7 +5455,7 @@ "message": "string", "sub": "string", "token": "string", - "ttl": "string", + "ttl": 0, "delivery": null } } diff --git a/package-lock.json b/package-lock.json index 241cfd8..4540aa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "seamless-auth-api", - "version": "0.6.0", + "version": "0.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "seamless-auth-api", - "version": "0.6.0", + "version": "0.7.0", "license": "AGPL-3.0-only", "dependencies": { "@asteasolutions/zod-to-openapi": "^8.4.3", "@seamless-auth/messaging": "^0.1.0", "@seamless-auth/messaging-aws": "^0.1.0", "@seamless-auth/messaging-twilio": "^0.1.0", - "@seamless-auth/types": "^0.5.0", + "@seamless-auth/types": "^0.6.0", "@simplewebauthn/server": "^13.1.1", "base64url": "^3.0.1", "bcrypt-ts": "^7.1.0", @@ -3393,9 +3393,9 @@ } }, "node_modules/@seamless-auth/types": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@seamless-auth/types/-/types-0.5.0.tgz", - "integrity": "sha512-T566YQu8FqUmqgte0A0iJpjTDXUKq/d/7uvLlXGXKtdl52Edo0r3iafL3kx4OM0cRJM63tBGe9s4MTjRUth6yA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@seamless-auth/types/-/types-0.6.0.tgz", + "integrity": "sha512-jsgSn6gAKFXpdKdQ0B4GconuKNWTQihCZLqqHmKYztolN4c3zMnrWrK3nQHup2a7q/TLxlk25HDZw2j4WxkjOA==", "license": "AGPL-3.0-only", "dependencies": { "zod": "^4.3.6" diff --git a/package.json b/package.json index 0062b60..bb9a120 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@seamless-auth/messaging": "^0.1.0", "@seamless-auth/messaging-aws": "^0.1.0", "@seamless-auth/messaging-twilio": "^0.1.0", - "@seamless-auth/types": "^0.5.0", + "@seamless-auth/types": "^0.6.0", "@simplewebauthn/server": "^13.1.1", "base64url": "^3.0.1", "bcrypt-ts": "^7.1.0", diff --git a/src/controllers/registration.ts b/src/controllers/registration.ts index ac5d183..fd1d2b2 100644 --- a/src/controllers/registration.ts +++ b/src/controllers/registration.ts @@ -158,7 +158,10 @@ export const register = async (req: Request, res: Response) => { message: 'Success', sub: user.id, token, - ttl: '300', + // Seconds, and it has to match the `5m` in signEphemeralToken. A caller + // sets its registration cookie from this, so a larger value here leaves a + // cookie outliving the token it carries. + ttl: 300, ...(delivery ? { delivery } : {}), }); } catch (error: unknown) { diff --git a/src/generated/api.ts b/src/generated/api.ts index 6b027d1..0f98e0e 100644 --- a/src/generated/api.ts +++ b/src/generated/api.ts @@ -5769,7 +5769,7 @@ export interface paths { * "message": "string", * "sub": "string", * "token": "string", - * "ttl": "string", + * "ttl": 0, * "delivery": null * } */ @@ -5777,7 +5777,7 @@ export interface paths { message: string; sub?: string; token?: string; - ttl?: string; + ttl?: number; delivery?: | { /** @enum {string} */