UNPKG

@atproto/oauth-client

Version:

OAuth client for ATPROTO PDS. This package serves as common base for environment-specific implementations (NodeJS, Browser, React-Native).

66 lines 2.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateClientMetadata = validateClientMetadata; const oauth_types_1 = require("@atproto/oauth-types"); const types_js_1 = require("./types.js"); const TOKEN_ENDPOINT_AUTH_METHOD = `token_endpoint_auth_method`; const TOKEN_ENDPOINT_AUTH_SIGNING_ALG = `token_endpoint_auth_signing_alg`; function validateClientMetadata(input, keyset) { if (input.jwks) { if (!keyset) { throw new TypeError(`Keyset must not be provided when jwks is provided`); } for (const key of input.jwks.keys) { if (!key.kid) { throw new TypeError(`Key must have a "kid" property`); } else if (!keyset.has(key.kid)) { throw new TypeError(`Key with kid "${key.kid}" not found in keyset`); } } } // Allow to pass a keyset and omit the jwks/jwks_uri properties if (!input.jwks && !input.jwks_uri && keyset?.size) { input = { ...input, jwks: keyset.toJSON() }; } const metadata = types_js_1.clientMetadataSchema.parse(input); // Validate client ID if (metadata.client_id.startsWith('http:')) { (0, oauth_types_1.assertOAuthLoopbackClientId)(metadata.client_id); } else { (0, oauth_types_1.assertOAuthDiscoverableClientId)(metadata.client_id); } const scopes = metadata.scope?.split(' '); if (!scopes?.includes('atproto')) { throw new TypeError(`Client metadata must include the "atproto" scope`); } if (!metadata.response_types.includes('code')) { throw new TypeError(`"response_types" must include "code"`); } if (!metadata.grant_types.includes('authorization_code')) { throw new TypeError(`"grant_types" must include "authorization_code"`); } const method = metadata[TOKEN_ENDPOINT_AUTH_METHOD]; switch (method) { case undefined: throw new TypeError(`${TOKEN_ENDPOINT_AUTH_METHOD} must be provided`); case 'none': if (metadata[TOKEN_ENDPOINT_AUTH_SIGNING_ALG]) { throw new TypeError(`${TOKEN_ENDPOINT_AUTH_SIGNING_ALG} must not be provided when ${TOKEN_ENDPOINT_AUTH_METHOD} is "${method}"`); } break; case 'private_key_jwt': if (!keyset?.size) { throw new TypeError(`A non-empty keyset must be provided when ${TOKEN_ENDPOINT_AUTH_METHOD} is "${method}"`); } if (!metadata[TOKEN_ENDPOINT_AUTH_SIGNING_ALG]) { throw new TypeError(`${TOKEN_ENDPOINT_AUTH_SIGNING_ALG} must be provided when ${TOKEN_ENDPOINT_AUTH_METHOD} is "${method}"`); } break; default: throw new TypeError(`Invalid "token_endpoint_auth_method" value: ${method}`); } return metadata; } //# sourceMappingURL=validate-client-metadata.js.map