From 91e40705b808585b8862e7c539fe51bd4bb566aa Mon Sep 17 00:00:00 2001 From: Mirko Mollik Date: Wed, 1 May 2024 20:29:21 +0200 Subject: [PATCH] add endpoint to delete a rp manually Signed-off-by: Mirko Mollik --- apps/verifier/src/RPManager.ts | 22 +++++++++++++++------- apps/verifier/src/main.ts | 12 ++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/apps/verifier/src/RPManager.ts b/apps/verifier/src/RPManager.ts index d071c69d..fbccd896 100644 --- a/apps/verifier/src/RPManager.ts +++ b/apps/verifier/src/RPManager.ts @@ -18,7 +18,7 @@ import { } from '@sphereon/did-auth-siop'; import { JWkResolver, encodeDidJWK } from './did.js'; import { readFileSync } from 'node:fs'; -import { join } from 'node:path'; +import { join, normalize, sep } from 'node:path'; import { VerifierRP } from './types.js'; import { SDJwtVcInstance } from '@sd-jwt/sd-jwt-vc'; import { KbVerifier, Verifier } from '@sd-jwt/types'; @@ -60,10 +60,12 @@ export class RPManager { let rp = this.rp.get(id); if (!rp) { rp = this.buildRP(id); - // checks every minute if the rp has active sessions. If there is none, the rp is removed. We want to do this so we can update the rp with new input without losing state. This approach could be improved since we are waiting around 4 minutes for the last finished request until the entries are removed. - setInterval(async () => { - this.remove(id); - }, 1000 * 60); + if (process.env.CONFIG_RELOAD) { + // checks every minute if the rp has active sessions. If there is none, the rp is removed. We want to do this so we can update the rp with new input without losing state. This approach could be improved since we are waiting around 4 minutes for the last finished request until the entries are removed. + setInterval(async () => { + this.remove(id); + }, 1000 * 60); + } this.rp.set(id, rp); } return rp; @@ -90,9 +92,15 @@ export class RPManager { console.log('Removed the rp'); } + // create the relying party private buildRP(id: string) { - // create the relying party - const verifierFile = readFileSync(join('templates', `${id}.json`), 'utf-8'); + // escape potential path traversal attacks + const safeId = normalize(id).split(sep).pop(); + // instead of reading a file, we could pass a storage reference. Then the storage can be implemented in different ways, like using a database or a file system. + const verifierFile = readFileSync( + join('templates', `${safeId}.json`), + 'utf-8' + ); if (!verifierFile) { throw new Error(`The verifier with the id ${id} is not supported.`); } diff --git a/apps/verifier/src/main.ts b/apps/verifier/src/main.ts index 90b29094..100dcec7 100644 --- a/apps/verifier/src/main.ts +++ b/apps/verifier/src/main.ts @@ -87,6 +87,18 @@ expressSupport.express.post( } ); +// only set this when reload is activated +if (process.env.CONFIG_RELOAD) { + /** + * This will remove a rp so it can be reloaded with new values + */ + expressSupport.express.delete('/siop/:rp', async (req, res) => { + const rpId = req.params.rp; + await rpManager.remove(rpId, true); + res.send(); + }); +} + expressSupport.express.get('/health', async (req, res) => { res.send('ok'); });