Fix unable to fetch web service tokens in app

This commit is contained in:
Samuel Elliott 2025-08-01 21:29:04 +01:00
parent 3bfee7559f
commit 2ddac1619f
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
5 changed files with 16 additions and 11 deletions

View File

@ -919,7 +919,8 @@ class CoralApiRequest<T = unknown> {
const decrypted = request_encryption instanceof ZncaApiNxapi ?
await request_encryption.decryptResponse(data,
this.flags[RequestFlagNxapiZncaApiRequestNsaAssertionSymbol]) :
request_encryption.auth?.has_nsa_assertion_scope &&
this.flags[RequestFlagNxapiZncaApiRequestNsaAssertionSymbol]) :
await request_encryption.decryptResponse(data);
const encryption: ResponseEncryption = {

View File

@ -554,7 +554,7 @@ export class NxapiZncaAuth {
{ id: string; secret: string; } |
{ id: string; } |
null = null;
request_scope = 'ca:gf ca:er ca:dr';
token: TokenData | null = null;
@ -626,6 +626,13 @@ export class NxapiZncaAuth {
return !!this.token && this.token.expires_at > Date.now();
}
get has_nsa_assertion_scope() {
return this.token?.result.scope ? !!this.token.result.scope.match(/\bca:ns\b/) :
this.client_assertion_provider && !this.client_credentials ?
!!this.client_assertion_provider.scope.match(/\bca:ns\b/) :
this.client_credentials ? !!this.request_scope.match(/\bca:ns\b/) : false;
}
async getAccessToken(): Promise<TokenResponse> {
const resource = this.protected_resource ?? (this.protected_resource = await this.getProtectedResource());
const refresh_token = this.refresh_token;
@ -658,6 +665,7 @@ export class NxapiZncaAuth {
body.append('client_assertion_type', type);
body.append('client_assertion', assertion);
body.set('scope', this.client_assertion_provider.scope);
} else {
if (resource.resource_metadata.resource_documentation) {
throw new TypeError('Client authentication not configured\n\n' +

View File

@ -59,7 +59,8 @@ export async function main(argv = process.argv.slice(2)) {
addUserAgent('unidentified-script');
}
setClientAssertionProvider(new ClientAssertionProvider(NXAPI_AUTH_CLI_CLIENT_ID));
setClientAssertionProvider(new ClientAssertionProvider(NXAPI_AUTH_CLI_CLIENT_ID, undefined,
'ca:gf ca:er ca:dr ca:na'));
const yargs = createYargs(argv);

View File

@ -1,4 +1,4 @@
import type { Arguments as ParentArguments } from '../nso/index.js';
import type { Arguments as ParentArguments } from './index.js';
import createDebug from '../../util/debug.js';
import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js';
import { initStorage } from '../../util/storage.js';
@ -32,13 +32,6 @@ export async function handler(argv: ArgumentsCamelCase<Arguments>) {
throw new Error('API proxy not supported');
}
if (!process.env.NXAPI_ZNCA_API_AUTH_SCOPE) {
// TODO: default cli/app clients should have this scope set automatically
// - custom clients won't be able to request this scope though so can't
// just be the default request scope
process.env.NXAPI_ZNCA_API_AUTH_SCOPE = 'ca:gf ca:er ca:dr ca:na';
}
const storage = await initStorage(argv.dataPath);
const user_na_id = argv.user ?? await storage.getItem('SelectedUser');

View File

@ -12,6 +12,7 @@ export function setClientAssertionProvider(provider: ClientAssertionProviderInte
}
export interface ClientAssertionProviderInterface {
scope: string;
create(aud: string, exp?: number): Promise<OAuthClientAssertion>;
}
export interface OAuthClientAssertion {
@ -24,6 +25,7 @@ export class ClientAssertionProvider implements ClientAssertionProviderInterface
readonly client_id: string,
// readonly iss = 'nxapi',
readonly iss = client_id,
public scope = 'ca:gf ca:er ca:dr',
) {}
async create(aud: string, exp = 60) {