Modified OAuthApp to properly handle additional scopes not defined in the auth Scopes enum
All checks were successful
Publish to Private NPM Registry / publish (push) Successful in 32s

This commit is contained in:
Alan Bridgeman 2026-04-03 06:55:03 -05:00
parent 8c1306522b
commit 54bfb3cd6f

View file

@ -14,7 +14,7 @@ import { HealthCheckableRequestClient } from '../utils/HealthCheckableRequestCli
import type { BridgemanAccessibleAppClaims } from './types/BridgemanAccessibleAppClaims.js'; import type { BridgemanAccessibleAppClaims } from './types/BridgemanAccessibleAppClaims.js';
interface BasicOAuthAppOptions { interface BasicOAuthAppOptions<TScopes extends string> {
// ------------------ // ------------------
// Basic app metadata // Basic app metadata
// ------------------ // ------------------
@ -39,7 +39,7 @@ interface BasicOAuthAppOptions {
contacts?: string[], contacts?: string[],
/** The "available" scopes (scopes an app token COULD ask for - token scopes would have to ask for this or a subset of this list) */ /** The "available" scopes (scopes an app token COULD ask for - token scopes would have to ask for this or a subset of this list) */
scopes?: Scopes[], scopes?: (TScopes | Scopes)[],
// ----------------------------------------------------- // -----------------------------------------------------
// Optional Mechanical Details (how the OAuth app works) // Optional Mechanical Details (how the OAuth app works)
@ -98,16 +98,16 @@ interface BasicOAuthAppOptions {
//addons?: Addon[], //addons?: Addon[],
}; };
type OAuthAppOptions<T extends BridgemanAccessibleAppClaims> = T & BasicOAuthAppOptions; type OAuthAppOptions<T extends BridgemanAccessibleAppClaims, TScopes extends string> = T & BasicOAuthAppOptions<TScopes>;
export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extends App { export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims, TScopes extends string> extends App {
private onAuth: OnAuthCallback; private onAuth: OnAuthCallback;
private saveSecret: (secret: string) => void | Promise<void>; private saveSecret: (secret: string) => void | Promise<void>;
private getSecret: () => Promise<string>; private getSecret: () => Promise<string>;
private options: OAuthAppOptions<TCustomClaims>; private options: OAuthAppOptions<TCustomClaims, TScopes>;
private client: Client<TCustomClaims>; private client: Client<TCustomClaims, TScopes>;
/** /**
* Create a new OAuth app * Create a new OAuth app
@ -158,17 +158,17 @@ export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extend
onAuth: OnAuthCallback, onAuth: OnAuthCallback,
saveSecret: (secret: string) => void | Promise<void>, saveSecret: (secret: string) => void | Promise<void>,
getSecret: () => Promise<string>, getSecret: () => Promise<string>,
options?: OAuthAppOptions<TCustomClaims> options?: OAuthAppOptions<TCustomClaims, TScopes>
) { ) {
super(); super();
this.onAuth = onAuth; this.onAuth = onAuth;
this.saveSecret = saveSecret; this.saveSecret = saveSecret;
this.getSecret = getSecret; this.getSecret = getSecret;
this.options = options ?? {} as OAuthAppOptions<TCustomClaims>; this.options = options ?? {} as OAuthAppOptions<TCustomClaims, TScopes>;
} }
/** Returns the OAuthApp's Client instance (which is useful for managing keys, creating resource request, etc...) */ /** Returns the OAuthApp's Client instance (which is useful for managing keys, creating resource request, etc...) */
getClient(): Client<TCustomClaims> { getClient(): Client<TCustomClaims, TScopes> {
return this.client; return this.client;
} }
@ -200,7 +200,7 @@ export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extend
.getRouter() .getRouter()
.addOutsideFrameworkRoute(BaseKeystore.WELL_KNOWN_URI); .addOutsideFrameworkRoute(BaseKeystore.WELL_KNOWN_URI);
this.client = await Client.setup<TCustomClaims>( this.client = await Client.setup<TCustomClaims, TScopes>(
app.getExpressApp(), app.getExpressApp(),
baseAppUrl, baseAppUrl,
this.onAuth, this.onAuth,
@ -322,7 +322,7 @@ export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extend
* *
* @param app The Express app object (that is now listening) * @param app The Express app object (that is now listening)
*/ */
private async onStart(app: App, callback?: (app: OAuthApp<TCustomClaims>) => void | Promise<void>) { private async onStart(app: App, callback?: (app: OAuthApp<TCustomClaims, TScopes>) => void | Promise<void>) {
try { try {
// Setup the OAuth client. // Setup the OAuth client.
// This is done here because we need the client to be serving/listening for requests for the auth library stuff to work // This is done here because we need the client to be serving/listening for requests for the auth library stuff to work
@ -350,7 +350,7 @@ export class OAuthApp<TCustomClaims extends BridgemanAccessibleAppClaims> extend
* And doesn't have to worry about the OAuth details to make this work. * And doesn't have to worry about the OAuth details to make this work.
* Though it does provide tweaking the OAuth details via options provided to the constructor. * Though it does provide tweaking the OAuth details via options provided to the constructor.
*/ */
async run<T extends Initializer>(initializer?: T, callback?: (app: OAuthApp<TCustomClaims>) => void | Promise<void>) { async run<T extends Initializer>(initializer?: T, callback?: (app: OAuthApp<TCustomClaims, TScopes>) => void | Promise<void>) {
await super.run(initializer, async (app: App) => this.onStart(app, callback)); await super.run(initializer, async (app: App) => this.onStart(app, callback));
} }
} }