add expiry tolerance if not dryRun to the admin premium unlock api

This commit is contained in:
Jonas Lochmann
2026-06-15 02:00:00 +02:00
parent 235115168f
commit 91cb44d244
3 changed files with 10 additions and 5 deletions
+3 -1
View File
@@ -100,7 +100,9 @@ request properties: ``purchaseToken``, ``purchaseId`` and ``dryRun``
- ``purchasetoken`` is a string which the client shows at the purchase screen - ``purchasetoken`` is a string which the client shows at the purchase screen
- ``purchaseId`` is the ID that is used at the bill - ``purchaseId`` is the ID that is used at the bill
- ``dryRun`` is a boolean; setting true will skip the actual unlocking - ``dryRun`` is a boolean
- setting true will skip the actual unlocking
- false will add a four week tolerance to the token expiry to permit checking now and unlocking later
- ``type`` is a string and must be ``year``, ``month`` or ``unpaid14`` - ``type`` is a string and must be ``year``, ``month`` or ``unpaid14``
### response ### response
+1 -1
View File
@@ -156,7 +156,7 @@ export const createAdminRouter = ({ database, websocket, eventHandler }: {
throw new BadRequest() throw new BadRequest()
} }
const tokenContent = await verifyIdentitifyToken(purchaseToken) const tokenContent = await verifyIdentitifyToken(purchaseToken, dryRun)
if (tokenContent.purpose !== 'purchase') { if (tokenContent.purpose !== 'purchase') {
res.json({ ok: false, error: 'token invalid', detail: 'wrong purpose' }) res.json({ ok: false, error: 'token invalid', detail: 'wrong purpose' })
+6 -3
View File
@@ -1,6 +1,6 @@
/* /*
* server component for the TimeLimit App * server component for the TimeLimit App
* Copyright (C) 2019 - 2022 Jonas Lochmann * Copyright (C) 2019 - 2026 Jonas Lochmann
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
@@ -33,12 +33,15 @@ export async function createIdentityToken({ purpose, familyId, userId, mail }: I
.join('\n') .join('\n')
} }
export async function verifyIdentitifyToken(token: string): Promise<IdentityTokenPayload> { export async function verifyIdentitifyToken(token: string, dryRun: boolean): Promise<IdentityTokenPayload> {
try { try {
const { payload } = await jwtVerify( const { payload } = await jwtVerify(
Buffer.from(token, 'base64').toString('ascii'), Buffer.from(token, 'base64').toString('ascii'),
getSignSecret(), getSignSecret(),
{ algorithms: ['HS512'] } {
algorithms: ['HS512'],
clockTolerance: dryRun ? 0 : '4w',
}
) )
if (!isIdentityTokenPayload(payload)) throw new BadPayloadException() if (!isIdentityTokenPayload(payload)) throw new BadPayloadException()