From ddf1b4f07f8fc104d972a2ab4a2573c110d998c0 Mon Sep 17 00:00:00 2001 From: matteo-cristino Date: Wed, 14 May 2025 11:10:30 +0200 Subject: [PATCH 1/2] chore: fix some eslint error --- eslint.config.mjs | 35 +++++++++++++++------------- pkg/db/test/e2e.ts | 2 +- pkg/ethereum/src/plugin.ts | 2 +- pkg/fs/test/plugin.ts | 3 ++- pkg/json-schema/src/plugin.ts | 9 ++++--- pkg/json-schema/test/e2e.ts | 2 +- pkg/oauth/src/authenticateHandler.ts | 10 ++++++-- pkg/oauth/src/authorizeHandler.ts | 2 +- pkg/oauth/src/isFormat.ts | 2 +- pkg/oauth/src/model.ts | 34 +++++++++++++-------------- pkg/oauth/src/plugin.ts | 14 +++++------ pkg/oauth/test/e2e.ts | 4 ++-- 12 files changed, 64 insertions(+), 55 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index afed2edc..425c8d06 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -6,20 +6,23 @@ import js from '@eslint/js'; import tseslint from 'typescript-eslint'; export default [ - js.configs.recommended, - ...tseslint.configs.recommended, - { - files: ['**/*.ts'], - rules: { - '@typescript-eslint/no-unused-vars': [ - 'error', - { - argsIgnorePattern: '^_', - varsIgnorePattern: '^_', - }, - ], - '@typescript-eslint/consistent-type-definitions': ['error', 'type'], - 'no-control-regex': 'off', - }, - }, + { + ignores: ['pkg/pocketbase/test/pb_migrations/*'], + }, + js.configs.recommended, + ...tseslint.configs.recommended, + { + files: ['**/*.ts'], + rules: { + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], + '@typescript-eslint/consistent-type-definitions': ['error', 'type'], + 'no-control-regex': 'off', + }, + }, ]; diff --git a/pkg/db/test/e2e.ts b/pkg/db/test/e2e.ts index 0ff2988c..2f1ee707 100644 --- a/pkg/db/test/e2e.ts +++ b/pkg/db/test/e2e.ts @@ -116,7 +116,7 @@ test.serial('Db read from a db and write in another one', async (t) => { let query = await Result2.findByPk(1) as Result1; query = query?.get({ plain: true }); res2 = JSON.parse(query?.["result"] ?? "{}"); - } catch (e) { + } catch { res2 = null; } sequelize2.close(); diff --git a/pkg/ethereum/src/plugin.ts b/pkg/ethereum/src/plugin.ts index 16256ec6..1dfbb79f 100644 --- a/pkg/ethereum/src/plugin.ts +++ b/pkg/ethereum/src/plugin.ts @@ -50,7 +50,7 @@ export const ethBytes = p.new( try { const dataRead = receipt.logs[0]?.data?.slice(2); return ctx.pass(dataRead?.toString() || ''); - } catch (e) { + } catch { return ctx.fail(new EthereumError('Empty transaction')); } }, diff --git a/pkg/fs/test/plugin.ts b/pkg/fs/test/plugin.ts index 71e88299..ef903c45 100644 --- a/pkg/fs/test/plugin.ts +++ b/pkg/fs/test/plugin.ts @@ -15,6 +15,7 @@ import { join } from 'node:path'; import * as os from 'node:os'; import http from 'http'; import { once } from 'events'; +import { AddressInfo } from 'node:net'; const zipBuffer = Buffer.from('UEsDBAoAAAAAADRzTFfps6IEBAAAAAQAAAAHABwAZm9vLnR4dFVUCQADs9cnZWELKWV1eAsAAQToAwAABOgDAABiYXIKUEsBAh4DCgAAAAAANHNMV+mzogQEAAAABAAAAAcAGAAAAAAAAQAAAICBAAAAAGZvby50eHRVVAUAA7PXJ2V1eAsAAQToAwAABOgDAABQSwUGAAAAAAEAAQBNAAAARQAAAAAA', 'base64'); @@ -26,7 +27,7 @@ const server = http.createServer((req, res) => { } }); await once(server.listen(0), 'listening'); // listen on random free port -const { port } = server.address() as any; +const { port } = server.address() as AddressInfo; const zipUrl = `http://localhost:${port}/`; // Tests in this file must be run serially, since we're modifying `process.env` diff --git a/pkg/json-schema/src/plugin.ts b/pkg/json-schema/src/plugin.ts index 97dd47a7..37c1319e 100644 --- a/pkg/json-schema/src/plugin.ts +++ b/pkg/json-schema/src/plugin.ts @@ -3,7 +3,8 @@ // SPDX-License-Identifier: AGPL-3.0-or-later import { Plugin } from '@slangroom/core'; -import { Ajv, type ValidationError } from 'ajv'; +import { Ajv, type ValidationError, type AnySchema } from 'ajv'; +import type { Jsonable } from '@slangroom/shared'; // read the version from the package.json import packageJson from '@slangroom/json-schema/package.json' with { type: 'json' }; @@ -38,18 +39,16 @@ export const validateJSON = p.new( PHRASE_VALIDATE_JSON, async (ctx) => { const data = ctx.fetch(ARG_JSON_DATA); - const schema = ctx.fetch(ARG_JSON_SCHEMA); + const schema = ctx.fetch(ARG_JSON_SCHEMA) as AnySchema; try { const ajv = new Ajv({ allErrors: true }); - // @ts-ignore const validate = ajv.compile(schema); validate(data); - // @ts-ignore return ctx.pass({ - errors: validate.errors ?? [], + errors: validate.errors as unknown as Jsonable[] ?? [], }); } catch (e) { return ctx.fail(new JsonSchemaError('JSON Schema not valid' + e.message)); diff --git a/pkg/json-schema/test/e2e.ts b/pkg/json-schema/test/e2e.ts index 700af432..01edd0aa 100644 --- a/pkg/json-schema/test/e2e.ts +++ b/pkg/json-schema/test/e2e.ts @@ -77,7 +77,7 @@ test('load invalid schema', async (t) => { }, }, }); - } catch (e) { + } catch { error = 'Invalid JSON schema'; } diff --git a/pkg/oauth/src/authenticateHandler.ts b/pkg/oauth/src/authenticateHandler.ts index 80362b9f..129231ec 100644 --- a/pkg/oauth/src/authenticateHandler.ts +++ b/pkg/oauth/src/authenticateHandler.ts @@ -24,6 +24,12 @@ import { importJWK, jwtVerify } from 'jose'; import bs58 from 'bs58'; import { InMemoryCache } from '@slangroom/oauth'; +type VerificationMethod = { + type?: string; + publicKeyBase58?: string; + [key: string]: unknown; +}; + export class AuthenticateHandler { addAcceptedScopesHeader: boolean | undefined; addAuthorizedScopesHeader: boolean | undefined; @@ -113,7 +119,7 @@ export class AuthenticateHandler { const result = await response.json(); - const base58Key = result.didDocument.verificationMethod.find((value: any) => value.type == 'EcdsaSecp256r1VerificationKey').publicKeyBase58; + const base58Key = result.didDocument.verificationMethod.find((value: VerificationMethod) => value?.type == 'EcdsaSecp256r1VerificationKey').publicKeyBase58; const uint8Key = bs58.decode(base58Key); const x_base64Key = Buffer.from(uint8Key.buffer.slice(0, 32)).toString('base64url'); const y_base64Key = Buffer.from(uint8Key.buffer.slice(32)).toString('base64url'); @@ -182,7 +188,7 @@ export class AuthenticateHandler { } const result = await response.json(); const credentials_supported = result.credential_configurations_supported; - var valid_credentials = Object.values(credentials_supported).some((value: any) => value.vct === scope); + const valid_credentials = Object.values(credentials_supported).some((value: any) => value.vct === scope); return valid_credentials; } diff --git a/pkg/oauth/src/authorizeHandler.ts b/pkg/oauth/src/authorizeHandler.ts index 0e26681d..d525a0db 100644 --- a/pkg/oauth/src/authorizeHandler.ts +++ b/pkg/oauth/src/authorizeHandler.ts @@ -414,7 +414,7 @@ export class AuthorizeHandler { */ async saveAuthorizationCode(authorizationCode: string, expiresAt: Date, redirectUri: string, scope: string[], client: Client, user: User, codeChallenge: string, codeChallengeMethod: string, authorization_details: { [key: string]: any }[], rand_uri: string) { - let code: AuthorizationCode = { + const code: AuthorizationCode = { authorizationCode: authorizationCode, expiresAt: expiresAt, redirectUri: redirectUri, diff --git a/pkg/oauth/src/isFormat.ts b/pkg/oauth/src/isFormat.ts index 458b6eba..393c6f99 100644 --- a/pkg/oauth/src/isFormat.ts +++ b/pkg/oauth/src/isFormat.ts @@ -15,7 +15,7 @@ const rules = { VSCHAR: /^[\u0020-\u007E]+$/ }; -/* eslint-enable no-control-regex */ + /** * Minimal, RFC 6749, compliant unicode validator. diff --git a/pkg/oauth/src/model.ts b/pkg/oauth/src/model.ts index 41f28919..1b805f77 100644 --- a/pkg/oauth/src/model.ts +++ b/pkg/oauth/src/model.ts @@ -143,7 +143,7 @@ export class InMemoryCache implements AuthorizationCodeModel { codeChallengeMethod: code['codeChallengeMethod'], }; - var keys = Object.keys(code); + const keys = Object.keys(code); keys.forEach((key: string) => { if (!codeSaved[key]) { codeSaved[key] = code[key]; @@ -169,7 +169,7 @@ export class InMemoryCache implements AuthorizationCodeModel { const base_uri = "urn:ietf:params:oauth:request_uri:"; const rand_uri = request_uri.replace(base_uri, ""); const auth_code = this.getAuthCodeFromUri(rand_uri); - let auth_details = this.getAuthorizationDetails(auth_code.authorizationCode); + const auth_details = this.getAuthorizationDetails(auth_code.authorizationCode); //TODO: case of multiple elem in auth_details if (auth_details[0]) { auth_details[0]['claims'] = data; @@ -187,7 +187,7 @@ export class InMemoryCache implements AuthorizationCodeModel { * */ getAuthorizationCode(authorizationCode: string): Promise { - var codes = this.codes.filter(function (code) { + const codes = this.codes.filter(function (code) { return code.authorizationCode === authorizationCode; }); return Promise.resolve(codes[0]); @@ -217,7 +217,7 @@ export class InMemoryCache implements AuthorizationCodeModel { * */ saveAuthorizationCode(code: Pick, client: Client, user: User, authorization_details?: { [key: string]: any }[], rand_uri?: string): Promise { - let codeSaved: AuthorizationCode = { + const codeSaved: AuthorizationCode = { authorizationCode: code.authorizationCode, expiresAt: code.expiresAt, redirectUri: code.redirectUri, @@ -257,7 +257,7 @@ export class InMemoryCache implements AuthorizationCodeModel { */ getAccessToken(bearerToken: string): Promise { - var tokens = this.tokens.filter(function (token) { + const tokens = this.tokens.filter(function (token) { return token.accessToken === bearerToken; }); @@ -269,7 +269,7 @@ export class InMemoryCache implements AuthorizationCodeModel { */ getRefreshToken(bearerToken: string) { - var tokens = this.tokens.filter(function (token) { + const tokens = this.tokens.filter(function (token) { return token.refreshToken === bearerToken; }); @@ -324,7 +324,7 @@ export class InMemoryCache implements AuthorizationCodeModel { tokenSaved['jkt'] = this.createJWKThumbprint(dpop_jwk['jwk']); } if (this.options && this.options['allowExtendedTokenAttributes']) { - var keys = Object.keys(token); + const keys = Object.keys(token); keys.forEach((key: string) => { if (!tokenSaved[key]) { tokenSaved[key] = token[key]; @@ -345,9 +345,9 @@ export class InMemoryCache implements AuthorizationCodeModel { async createServerJWS(clientId: string) { if (this.serverData.jwk == null) throw new OAuthError("Missing server private JWK"); - let privateKey = await importJWK(this.serverData.jwk); - let alg = this.serverData.jwk.alg || 'ES256'; - let public_jwk: JWK = { + const privateKey = await importJWK(this.serverData.jwk); + const alg = this.serverData.jwk.alg || 'ES256'; + const public_jwk: JWK = { kty: this.serverData.jwk.kty!, x: this.serverData.jwk.x!, y: this.serverData.jwk.y!, @@ -388,7 +388,7 @@ export class InMemoryCache implements AuthorizationCodeModel { // For reference see Section 4.3 of RFC9449 https://datatracker.ietf.org/doc/html/rfc9449.html async verifyDpopProof(dpop: string, request: Request) { - let FIVE_MIN = 300000; + const FIVE_MIN = 300000; const defaultValues = { typ: 'dpop+jwt', alg: 'ES256', @@ -429,9 +429,9 @@ export class InMemoryCache implements AuthorizationCodeModel { async verifyDpopHeader(request: Request) { if (request.headers) { - var dpop = request.headers['dpop']; + const dpop = request.headers['dpop']; if (dpop) { - var check = await this.verifyDpopProof(dpop, request); + const check = await this.verifyDpopProof(dpop, request); if (!check) throw new OAuthError('Invalid request: DPoP header parameter is not valid'); const header = decodeProtectedHeader(dpop); const dpop_saved = { id: request.body['client_id'], jwk: header.jwk }; @@ -442,7 +442,7 @@ export class InMemoryCache implements AuthorizationCodeModel { } getDpopJWK(id: string) { - var jwks = this.dpop_jwks.filter(function (dpop_jwk: any) { + const jwks = this.dpop_jwks.filter(function (dpop_jwk: any) { return dpop_jwk.id === id; }); return Promise.resolve(jwks[0]); @@ -473,8 +473,8 @@ export class InMemoryCache implements AuthorizationCodeModel { } const result = await response.json(); const credentials_supported: { [key: string]: { vct: string, claims?: { [key: string]: { mandatory?: boolean }}}} = result.credential_configurations_supported; - var valid_credentials = []; - var credential_claims = new Map(); + const valid_credentials = []; + const credential_claims = new Map(); for (const value of Object.values(credentials_supported)) { if (value.vct === scope) { @@ -509,7 +509,7 @@ export class InMemoryCache implements AuthorizationCodeModel { throw new OAuthError('Invalid request: needed resource to verify scope'); } - var verified_credentials = await this.verifyCredentialId(scope[0]!, resource); + const verified_credentials = await this.verifyCredentialId(scope[0]!, resource); if (verified_credentials.valid_credentials.length > 0) return Promise.resolve(scope); else return false; diff --git a/pkg/oauth/src/plugin.ts b/pkg/oauth/src/plugin.ts index 27d3511c..5705148e 100644 --- a/pkg/oauth/src/plugin.ts +++ b/pkg/oauth/src/plugin.ts @@ -24,7 +24,7 @@ const p = new Plugin(); /* Parse QueryString using String Splitting */ function parseQueryStringToDictionary(queryString: string) { - var dictionary: { [key: string]: string } = {}; + const dictionary: { [key: string]: string } = {}; // remove the '?' from the beginning of the // if it exists @@ -33,16 +33,16 @@ function parseQueryStringToDictionary(queryString: string) { } // Step 1: separate out each key/value pair - var parts = queryString.split('&'); + const parts = queryString.split('&'); - for (var i = 0; i < parts.length; i++) { - var p = parts[i]; + for (let i = 0; i < parts.length; i++) { + const p = parts[i]; // Step 2: Split Key/Value pair - var keyValuePair = p!.split('='); + const keyValuePair = p!.split('='); // Step 3: Add Key/Value pair to Dictionary object - var key = keyValuePair[0]; - var value = keyValuePair[1]; + const key = keyValuePair[0]; + let value = keyValuePair[1]; // decode URI encoded string value = decodeURIComponent(value!); diff --git a/pkg/oauth/test/e2e.ts b/pkg/oauth/test/e2e.ts index 065614c0..23beded6 100644 --- a/pkg/oauth/test/e2e.ts +++ b/pkg/oauth/test/e2e.ts @@ -69,7 +69,7 @@ const server = { async function create_dpop_proof() { //this is done client side for token request // here for now, just for testing - var private_jwk = { + const private_jwk = { kty: 'EC', x: 'iyuaHgjseiWTdKd_EuhxO43oayK05z_wEb2SlsxofSo', y: 'EJBrgZE_wqm3P0bPuuYpO-5wbEbk9xy-8hdOiVODjOM', @@ -77,7 +77,7 @@ async function create_dpop_proof() { crv: 'P-256', }; - var privateKey = await importJWK(private_jwk); + const privateKey = await importJWK(private_jwk); const dpop = new SignJWT({ jti: randomBytes(16).toString('base64url'), From 6d45319e05e45cfecbc059577456f4b1e9b486f1 Mon Sep 17 00:00:00 2001 From: matteo-cristino Date: Wed, 14 May 2025 11:27:19 +0200 Subject: [PATCH 2/2] chore: fix more eslint errors --- pkg/oauth/src/plugin.ts | 4 ++-- pkg/pocketbase/src/plugin.ts | 4 ++-- pkg/wallet/src/plugin.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/oauth/src/plugin.ts b/pkg/oauth/src/plugin.ts index 5705148e..8484d8ee 100644 --- a/pkg/oauth/src/plugin.ts +++ b/pkg/oauth/src/plugin.ts @@ -76,8 +76,8 @@ const getInMemoryCache = ( return inMemoryCache; }; -let authenticateHandler: any; -const getAuthenticateHandler = (model: InMemoryCache, authenticationUrl?: string): any => { +let authenticateHandler: AuthenticateHandler; +const getAuthenticateHandler = (model: InMemoryCache, authenticationUrl?: string): AuthenticateHandler => { if (!authenticateHandler) { authenticateHandler = new AuthenticateHandler({ model: model }, authenticationUrl); } diff --git a/pkg/pocketbase/src/plugin.ts b/pkg/pocketbase/src/plugin.ts index 17bc2526..7422d9ce 100644 --- a/pkg/pocketbase/src/plugin.ts +++ b/pkg/pocketbase/src/plugin.ts @@ -22,10 +22,10 @@ export class PocketBaseError extends Error { let pb: PocketBase; const p = new Plugin(); -const serverUrlSchema = z.literal( +const _serverUrlSchema = z.literal( `http${z.union([z.literal('s'), z.literal('')])}://${z.string()}/`, ); -export type ServerUrl = z.infer; +export type ServerUrl = z.infer; const credentialsSchema = z.object({ email: z.string().email(), diff --git a/pkg/wallet/src/plugin.ts b/pkg/wallet/src/plugin.ts index 015ee059..91c43030 100644 --- a/pkg/wallet/src/plugin.ts +++ b/pkg/wallet/src/plugin.ts @@ -286,7 +286,7 @@ export const prettyPrintSdJwt = p.new(['token'], 'pretty print sd jwt', async (c const tryDecode = (s: string) => { try { return JSON.parse(atob(s)); - } catch (e) { + } catch { return s; } };