@apoa/core 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -23
- package/dist/index.cjs +177 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -1
- package/dist/index.d.ts +69 -1
- package/dist/index.js +175 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -235,6 +235,35 @@ interface APOAClientOptions {
|
|
|
235
235
|
keyResolver?: KeyResolver;
|
|
236
236
|
defaultSigningOptions?: Partial<SigningOptions>;
|
|
237
237
|
}
|
|
238
|
+
/** Options for the application-facing APOA facade. */
|
|
239
|
+
interface APOAOptions extends Omit<APOAClientOptions, 'defaultSigningOptions'> {
|
|
240
|
+
privateKey?: CryptoKey;
|
|
241
|
+
algorithm?: 'EdDSA' | 'ES256';
|
|
242
|
+
kid?: string;
|
|
243
|
+
}
|
|
244
|
+
/** Duration string for convenience expiry fields, e.g. `15m`, `2h`, `30d`. */
|
|
245
|
+
type DurationString = `${number}${'s' | 'm' | 'h' | 'd'}`;
|
|
246
|
+
/** One-service grant input accepted by the application-facing facade. */
|
|
247
|
+
interface SimpleGrantInput {
|
|
248
|
+
principal: string | Principal;
|
|
249
|
+
agent: string | Agent;
|
|
250
|
+
service?: string;
|
|
251
|
+
scopes?: string[];
|
|
252
|
+
services?: ServiceAuthorization[];
|
|
253
|
+
constraints?: ConstraintMap;
|
|
254
|
+
rules?: Rule[];
|
|
255
|
+
expires?: Date | string;
|
|
256
|
+
expiresIn?: DurationString;
|
|
257
|
+
revocable?: boolean;
|
|
258
|
+
delegatable?: boolean;
|
|
259
|
+
maxDelegationDepth?: number;
|
|
260
|
+
metadata?: TokenMetadata;
|
|
261
|
+
accessMode?: AccessMode;
|
|
262
|
+
browserConfig?: BrowserSessionConfig;
|
|
263
|
+
apiConfig?: APIAccessConfig;
|
|
264
|
+
agentProvider?: AgentProvider;
|
|
265
|
+
legal?: LegalFramework;
|
|
266
|
+
}
|
|
238
267
|
/** The configured APOA client. */
|
|
239
268
|
interface APOAClient {
|
|
240
269
|
createToken(definition: APOADefinition, options?: SigningOptions): Promise<APOAToken>;
|
|
@@ -520,6 +549,24 @@ declare function delegate(parentToken: APOAToken, childDef: DelegationDefinition
|
|
|
520
549
|
*/
|
|
521
550
|
declare function verifyChain(chain: DelegationChain, store?: RevocationStore): Promise<ChainVerificationResult>;
|
|
522
551
|
|
|
552
|
+
type DefinitionLike = {
|
|
553
|
+
parentToken?: unknown;
|
|
554
|
+
delegationChain?: unknown;
|
|
555
|
+
};
|
|
556
|
+
type TokenLike = {
|
|
557
|
+
parentToken?: unknown;
|
|
558
|
+
definition?: DefinitionLike;
|
|
559
|
+
};
|
|
560
|
+
/**
|
|
561
|
+
* Return ancestor token IDs referenced by a token-like object.
|
|
562
|
+
*
|
|
563
|
+
* Canonical SDK tokens use `parentToken` for the direct parent. Some transport
|
|
564
|
+
* adapters also carry `definition.delegationChain` snapshots or message
|
|
565
|
+
* metadata with ancestor IDs. This helper normalizes those forms so revocation
|
|
566
|
+
* checks can consistently include every known ancestor.
|
|
567
|
+
*/
|
|
568
|
+
declare function getDelegationAncestorIds(input: APOAToken | TokenLike | DefinitionLike): string[];
|
|
569
|
+
|
|
523
570
|
/** A JSON Web Key as defined by RFC 7517. */
|
|
524
571
|
interface JWK {
|
|
525
572
|
kty: string;
|
|
@@ -578,4 +625,25 @@ declare function createJWKSResolver(url: string, options?: JWKSResolverOptions):
|
|
|
578
625
|
*/
|
|
579
626
|
declare function createClient(options?: APOAClientOptions): APOAClient;
|
|
580
627
|
|
|
581
|
-
|
|
628
|
+
/**
|
|
629
|
+
* Application-facing APOA facade.
|
|
630
|
+
*
|
|
631
|
+
* This keeps the protocol-level APIs intact while giving app developers a
|
|
632
|
+
* smaller first path: configure once, then use namespaced resources.
|
|
633
|
+
*/
|
|
634
|
+
declare class APOA {
|
|
635
|
+
private readonly client;
|
|
636
|
+
readonly tokens: {
|
|
637
|
+
create: (definition: APOADefinition, options?: SigningOptions) => Promise<APOAToken>;
|
|
638
|
+
createGrant: (input: SimpleGrantInput, options?: SigningOptions) => Promise<APOAToken>;
|
|
639
|
+
validate: (token: string | APOAToken, options?: Omit<ValidationOptions, 'revocationStore'>) => Promise<ValidationResult>;
|
|
640
|
+
parse: (input: string, format?: 'yaml' | 'json') => APOADefinition;
|
|
641
|
+
};
|
|
642
|
+
readonly authorizations: {
|
|
643
|
+
check: (token: APOAToken, service: string, action: string, options?: Omit<AuthorizeOptions, 'revocationStore' | 'auditStore'>) => Promise<AuthorizationResult>;
|
|
644
|
+
};
|
|
645
|
+
constructor(options?: APOAOptions);
|
|
646
|
+
generateKeyPair(algorithm?: 'EdDSA' | 'ES256'): Promise<CryptoKeyPair>;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
export { type APIAccessConfig, APOA, type APOAClient, type APOAClientOptions, type APOADefinition, APOAError, type APOAOptions, type APOAToken, type AccessMode, type Agent, type AgentProvider, AttenuationViolationError, type AuditDetailValue, type AuditEntry, type AuditQueryOptions, type AuditStore, type AuthorizationResult, type AuthorizeOptions, type BrowserSessionConfig, ChainVerificationError, type ChainVerificationResult, type ConstraintMap, type ConstraintValue, DefinitionValidationError, type DelegationChain, type DelegationDefinition, type DurationString, type JWK, type JWKS, type JWKSResolverOptions, type KeyResolver, type LegalFramework, MemoryAuditStore, MemoryRevocationStore, MetadataValidationError, type MetadataValue, type OnRuleViolation, type Principal, type PublicKeyToJWKOptions, RevocationError, type RevocationOptions, type RevocationRecord, type RevocationStore, type Rule, RuleEnforcementError, type RuleViolation, type ScopeCheckResult, ScopeViolationError, type ServiceAuthorization, type SigningOptions, type SimpleGrantInput, TokenExpiredError, type TokenMetadata, type ValidationOptions, type ValidationResult, authorize, buildJWKS, cascadeRevoke, checkConstraint, checkScope, createClient, createJWKSResolver, createToken, decodeHeader, delegate, generateKeyPair, getAuditTrail, getAuditTrailByService, getDelegationAncestorIds, isBeforeNotBefore, isExpired, isRevoked, logAction, matchScope, parseDefinition, parseScope, publicKeyToJWK, revoke, sign, signToken, validateToken, verify, verifyAttenuation, verifyChain, verifySignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -235,6 +235,35 @@ interface APOAClientOptions {
|
|
|
235
235
|
keyResolver?: KeyResolver;
|
|
236
236
|
defaultSigningOptions?: Partial<SigningOptions>;
|
|
237
237
|
}
|
|
238
|
+
/** Options for the application-facing APOA facade. */
|
|
239
|
+
interface APOAOptions extends Omit<APOAClientOptions, 'defaultSigningOptions'> {
|
|
240
|
+
privateKey?: CryptoKey;
|
|
241
|
+
algorithm?: 'EdDSA' | 'ES256';
|
|
242
|
+
kid?: string;
|
|
243
|
+
}
|
|
244
|
+
/** Duration string for convenience expiry fields, e.g. `15m`, `2h`, `30d`. */
|
|
245
|
+
type DurationString = `${number}${'s' | 'm' | 'h' | 'd'}`;
|
|
246
|
+
/** One-service grant input accepted by the application-facing facade. */
|
|
247
|
+
interface SimpleGrantInput {
|
|
248
|
+
principal: string | Principal;
|
|
249
|
+
agent: string | Agent;
|
|
250
|
+
service?: string;
|
|
251
|
+
scopes?: string[];
|
|
252
|
+
services?: ServiceAuthorization[];
|
|
253
|
+
constraints?: ConstraintMap;
|
|
254
|
+
rules?: Rule[];
|
|
255
|
+
expires?: Date | string;
|
|
256
|
+
expiresIn?: DurationString;
|
|
257
|
+
revocable?: boolean;
|
|
258
|
+
delegatable?: boolean;
|
|
259
|
+
maxDelegationDepth?: number;
|
|
260
|
+
metadata?: TokenMetadata;
|
|
261
|
+
accessMode?: AccessMode;
|
|
262
|
+
browserConfig?: BrowserSessionConfig;
|
|
263
|
+
apiConfig?: APIAccessConfig;
|
|
264
|
+
agentProvider?: AgentProvider;
|
|
265
|
+
legal?: LegalFramework;
|
|
266
|
+
}
|
|
238
267
|
/** The configured APOA client. */
|
|
239
268
|
interface APOAClient {
|
|
240
269
|
createToken(definition: APOADefinition, options?: SigningOptions): Promise<APOAToken>;
|
|
@@ -520,6 +549,24 @@ declare function delegate(parentToken: APOAToken, childDef: DelegationDefinition
|
|
|
520
549
|
*/
|
|
521
550
|
declare function verifyChain(chain: DelegationChain, store?: RevocationStore): Promise<ChainVerificationResult>;
|
|
522
551
|
|
|
552
|
+
type DefinitionLike = {
|
|
553
|
+
parentToken?: unknown;
|
|
554
|
+
delegationChain?: unknown;
|
|
555
|
+
};
|
|
556
|
+
type TokenLike = {
|
|
557
|
+
parentToken?: unknown;
|
|
558
|
+
definition?: DefinitionLike;
|
|
559
|
+
};
|
|
560
|
+
/**
|
|
561
|
+
* Return ancestor token IDs referenced by a token-like object.
|
|
562
|
+
*
|
|
563
|
+
* Canonical SDK tokens use `parentToken` for the direct parent. Some transport
|
|
564
|
+
* adapters also carry `definition.delegationChain` snapshots or message
|
|
565
|
+
* metadata with ancestor IDs. This helper normalizes those forms so revocation
|
|
566
|
+
* checks can consistently include every known ancestor.
|
|
567
|
+
*/
|
|
568
|
+
declare function getDelegationAncestorIds(input: APOAToken | TokenLike | DefinitionLike): string[];
|
|
569
|
+
|
|
523
570
|
/** A JSON Web Key as defined by RFC 7517. */
|
|
524
571
|
interface JWK {
|
|
525
572
|
kty: string;
|
|
@@ -578,4 +625,25 @@ declare function createJWKSResolver(url: string, options?: JWKSResolverOptions):
|
|
|
578
625
|
*/
|
|
579
626
|
declare function createClient(options?: APOAClientOptions): APOAClient;
|
|
580
627
|
|
|
581
|
-
|
|
628
|
+
/**
|
|
629
|
+
* Application-facing APOA facade.
|
|
630
|
+
*
|
|
631
|
+
* This keeps the protocol-level APIs intact while giving app developers a
|
|
632
|
+
* smaller first path: configure once, then use namespaced resources.
|
|
633
|
+
*/
|
|
634
|
+
declare class APOA {
|
|
635
|
+
private readonly client;
|
|
636
|
+
readonly tokens: {
|
|
637
|
+
create: (definition: APOADefinition, options?: SigningOptions) => Promise<APOAToken>;
|
|
638
|
+
createGrant: (input: SimpleGrantInput, options?: SigningOptions) => Promise<APOAToken>;
|
|
639
|
+
validate: (token: string | APOAToken, options?: Omit<ValidationOptions, 'revocationStore'>) => Promise<ValidationResult>;
|
|
640
|
+
parse: (input: string, format?: 'yaml' | 'json') => APOADefinition;
|
|
641
|
+
};
|
|
642
|
+
readonly authorizations: {
|
|
643
|
+
check: (token: APOAToken, service: string, action: string, options?: Omit<AuthorizeOptions, 'revocationStore' | 'auditStore'>) => Promise<AuthorizationResult>;
|
|
644
|
+
};
|
|
645
|
+
constructor(options?: APOAOptions);
|
|
646
|
+
generateKeyPair(algorithm?: 'EdDSA' | 'ES256'): Promise<CryptoKeyPair>;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
export { type APIAccessConfig, APOA, type APOAClient, type APOAClientOptions, type APOADefinition, APOAError, type APOAOptions, type APOAToken, type AccessMode, type Agent, type AgentProvider, AttenuationViolationError, type AuditDetailValue, type AuditEntry, type AuditQueryOptions, type AuditStore, type AuthorizationResult, type AuthorizeOptions, type BrowserSessionConfig, ChainVerificationError, type ChainVerificationResult, type ConstraintMap, type ConstraintValue, DefinitionValidationError, type DelegationChain, type DelegationDefinition, type DurationString, type JWK, type JWKS, type JWKSResolverOptions, type KeyResolver, type LegalFramework, MemoryAuditStore, MemoryRevocationStore, MetadataValidationError, type MetadataValue, type OnRuleViolation, type Principal, type PublicKeyToJWKOptions, RevocationError, type RevocationOptions, type RevocationRecord, type RevocationStore, type Rule, RuleEnforcementError, type RuleViolation, type ScopeCheckResult, ScopeViolationError, type ServiceAuthorization, type SigningOptions, type SimpleGrantInput, TokenExpiredError, type TokenMetadata, type ValidationOptions, type ValidationResult, authorize, buildJWKS, cascadeRevoke, checkConstraint, checkScope, createClient, createJWKSResolver, createToken, decodeHeader, delegate, generateKeyPair, getAuditTrail, getAuditTrailByService, getDelegationAncestorIds, isBeforeNotBefore, isExpired, isRevoked, logAction, matchScope, parseDefinition, parseScope, publicKeyToJWK, revoke, sign, signToken, validateToken, verify, verifyAttenuation, verifyChain, verifySignature };
|
package/dist/index.js
CHANGED
|
@@ -1137,6 +1137,37 @@ function checkAttenuation(parent, child, index, errors) {
|
|
|
1137
1137
|
}
|
|
1138
1138
|
}
|
|
1139
1139
|
|
|
1140
|
+
// src/delegation/ancestors.ts
|
|
1141
|
+
function getDelegationAncestorIds(input) {
|
|
1142
|
+
const ids = [];
|
|
1143
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1144
|
+
const push = (value) => {
|
|
1145
|
+
if (typeof value !== "string" || value.length === 0 || seen.has(value)) {
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
seen.add(value);
|
|
1149
|
+
ids.push(value);
|
|
1150
|
+
};
|
|
1151
|
+
const token = input;
|
|
1152
|
+
const definition = hasDefinition(input) ? token.definition : input;
|
|
1153
|
+
push(token.parentToken);
|
|
1154
|
+
push(definition?.parentToken);
|
|
1155
|
+
const chain = definition?.delegationChain;
|
|
1156
|
+
if (Array.isArray(chain)) {
|
|
1157
|
+
for (const link of chain) {
|
|
1158
|
+
if (typeof link === "string") {
|
|
1159
|
+
push(link);
|
|
1160
|
+
} else if (link && typeof link === "object") {
|
|
1161
|
+
push(link.parentTokenId);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
return ids;
|
|
1166
|
+
}
|
|
1167
|
+
function hasDefinition(input) {
|
|
1168
|
+
return Boolean(input && typeof input === "object" && "definition" in input);
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1140
1171
|
// src/jwks/index.ts
|
|
1141
1172
|
import * as jose3 from "jose";
|
|
1142
1173
|
async function publicKeyToJWK(publicKey, options) {
|
|
@@ -1221,7 +1252,9 @@ function createClient(options) {
|
|
|
1221
1252
|
const defaultSigningOptions = options?.defaultSigningOptions;
|
|
1222
1253
|
function mergeSigningOptions(opts) {
|
|
1223
1254
|
if (!opts && !defaultSigningOptions?.privateKey) {
|
|
1224
|
-
throw new Error(
|
|
1255
|
+
throw new Error(
|
|
1256
|
+
"APOA needs a private key to create tokens. Pass `privateKey` to `new APOA({ privateKey })`, configure `createClient({ defaultSigningOptions: { privateKey } })`, or pass signing options to `createToken(...)`."
|
|
1257
|
+
);
|
|
1225
1258
|
}
|
|
1226
1259
|
return {
|
|
1227
1260
|
...defaultSigningOptions,
|
|
@@ -1282,7 +1315,147 @@ function createClient(options) {
|
|
|
1282
1315
|
}
|
|
1283
1316
|
};
|
|
1284
1317
|
}
|
|
1318
|
+
|
|
1319
|
+
// src/apoa.ts
|
|
1320
|
+
var APOA = class {
|
|
1321
|
+
client;
|
|
1322
|
+
tokens;
|
|
1323
|
+
authorizations;
|
|
1324
|
+
constructor(options = {}) {
|
|
1325
|
+
const { privateKey, algorithm, kid, ...clientOptions } = options;
|
|
1326
|
+
this.client = createClient({
|
|
1327
|
+
...clientOptions,
|
|
1328
|
+
defaultSigningOptions: privateKey ? { privateKey, algorithm, kid } : void 0
|
|
1329
|
+
});
|
|
1330
|
+
this.tokens = {
|
|
1331
|
+
create: (definition, signingOptions) => this.client.createToken(definition, signingOptions),
|
|
1332
|
+
createGrant: async (input, signingOptions) => this.client.createToken(normalizeGrantInput(input), signingOptions),
|
|
1333
|
+
validate: (token, validationOptions) => this.client.validateToken(token, validationOptions),
|
|
1334
|
+
parse: (input, format) => this.client.parseDefinition(input, format)
|
|
1335
|
+
};
|
|
1336
|
+
this.authorizations = {
|
|
1337
|
+
check: (token, service, action, authorizeOptions) => this.client.authorize(token, service, action, authorizeOptions)
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
async generateKeyPair(algorithm) {
|
|
1341
|
+
return this.client.generateKeyPair(algorithm);
|
|
1342
|
+
}
|
|
1343
|
+
};
|
|
1344
|
+
function normalizeGrantInput(input) {
|
|
1345
|
+
const errors = [];
|
|
1346
|
+
if (!input || typeof input !== "object") {
|
|
1347
|
+
throw invalidGrantInput(["input must be an object"]);
|
|
1348
|
+
}
|
|
1349
|
+
const principal = normalizePrincipal(input.principal, errors);
|
|
1350
|
+
const agent = normalizeAgent(input.agent, errors);
|
|
1351
|
+
const services = normalizeServices(input, errors);
|
|
1352
|
+
const expires = normalizeExpires(input, errors);
|
|
1353
|
+
if (errors.length > 0 || !principal || !agent || services.length === 0 || !expires) {
|
|
1354
|
+
throw invalidGrantInput(errors);
|
|
1355
|
+
}
|
|
1356
|
+
return {
|
|
1357
|
+
principal,
|
|
1358
|
+
agent,
|
|
1359
|
+
services,
|
|
1360
|
+
expires,
|
|
1361
|
+
...input.rules ? { rules: input.rules } : {},
|
|
1362
|
+
...input.revocable !== void 0 ? { revocable: input.revocable } : {},
|
|
1363
|
+
...input.delegatable !== void 0 ? { delegatable: input.delegatable } : {},
|
|
1364
|
+
...input.maxDelegationDepth !== void 0 ? { maxDelegationDepth: input.maxDelegationDepth } : {},
|
|
1365
|
+
...input.metadata ? { metadata: input.metadata } : {},
|
|
1366
|
+
...input.agentProvider ? { agentProvider: input.agentProvider } : {},
|
|
1367
|
+
...input.legal ? { legal: input.legal } : {}
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
function normalizePrincipal(principal, errors) {
|
|
1371
|
+
if (typeof principal === "string" && principal.trim()) {
|
|
1372
|
+
return { id: principal.trim() };
|
|
1373
|
+
}
|
|
1374
|
+
if (principal && typeof principal === "object" && principal.id) {
|
|
1375
|
+
return principal;
|
|
1376
|
+
}
|
|
1377
|
+
errors.push("principal is required; pass a DID string or { id }");
|
|
1378
|
+
return void 0;
|
|
1379
|
+
}
|
|
1380
|
+
function normalizeAgent(agent, errors) {
|
|
1381
|
+
if (typeof agent === "string" && agent.trim()) {
|
|
1382
|
+
return { id: agent.trim() };
|
|
1383
|
+
}
|
|
1384
|
+
if (agent && typeof agent === "object" && agent.id) {
|
|
1385
|
+
return agent;
|
|
1386
|
+
}
|
|
1387
|
+
errors.push("agent is required; pass a DID string or { id }");
|
|
1388
|
+
return void 0;
|
|
1389
|
+
}
|
|
1390
|
+
function normalizeServices(input, errors) {
|
|
1391
|
+
if (input.services) {
|
|
1392
|
+
if (!Array.isArray(input.services) || input.services.length === 0) {
|
|
1393
|
+
errors.push("services must be a non-empty array when provided");
|
|
1394
|
+
return [];
|
|
1395
|
+
}
|
|
1396
|
+
return input.services;
|
|
1397
|
+
}
|
|
1398
|
+
if (!input.service) {
|
|
1399
|
+
errors.push("service is required unless services is provided");
|
|
1400
|
+
return [];
|
|
1401
|
+
}
|
|
1402
|
+
if (!input.scopes || !Array.isArray(input.scopes) || input.scopes.length === 0) {
|
|
1403
|
+
errors.push("scopes must be a non-empty array unless services is provided");
|
|
1404
|
+
return [];
|
|
1405
|
+
}
|
|
1406
|
+
return [{
|
|
1407
|
+
service: input.service,
|
|
1408
|
+
scopes: input.scopes,
|
|
1409
|
+
...input.constraints ? { constraints: input.constraints } : {},
|
|
1410
|
+
...input.accessMode ? { accessMode: input.accessMode } : {},
|
|
1411
|
+
...input.browserConfig ? { browserConfig: input.browserConfig } : {},
|
|
1412
|
+
...input.apiConfig ? { apiConfig: input.apiConfig } : {}
|
|
1413
|
+
}];
|
|
1414
|
+
}
|
|
1415
|
+
function normalizeExpires(input, errors) {
|
|
1416
|
+
if (input.expires && input.expiresIn) {
|
|
1417
|
+
errors.push("pass either expires or expiresIn, not both");
|
|
1418
|
+
return void 0;
|
|
1419
|
+
}
|
|
1420
|
+
if (input.expires) {
|
|
1421
|
+
return input.expires;
|
|
1422
|
+
}
|
|
1423
|
+
if (input.expiresIn) {
|
|
1424
|
+
return parseDurationFromNow(input.expiresIn);
|
|
1425
|
+
}
|
|
1426
|
+
errors.push("expires or expiresIn is required");
|
|
1427
|
+
return void 0;
|
|
1428
|
+
}
|
|
1429
|
+
function parseDurationFromNow(duration) {
|
|
1430
|
+
const match = /^(\d+)([smhd])$/.exec(duration);
|
|
1431
|
+
if (!match) {
|
|
1432
|
+
throw invalidGrantInput([
|
|
1433
|
+
`expiresIn must use a clear duration like '15m', '2h', or '30d'`
|
|
1434
|
+
]);
|
|
1435
|
+
}
|
|
1436
|
+
const amount = Number(match[1]);
|
|
1437
|
+
if (!Number.isSafeInteger(amount) || amount <= 0) {
|
|
1438
|
+
throw invalidGrantInput(["expiresIn duration must be a positive integer"]);
|
|
1439
|
+
}
|
|
1440
|
+
const unitMs = {
|
|
1441
|
+
s: 1e3,
|
|
1442
|
+
m: 60 * 1e3,
|
|
1443
|
+
h: 60 * 60 * 1e3,
|
|
1444
|
+
d: 24 * 60 * 60 * 1e3
|
|
1445
|
+
};
|
|
1446
|
+
return new Date(Date.now() + amount * unitMs[match[2]]);
|
|
1447
|
+
}
|
|
1448
|
+
function invalidGrantInput(errors) {
|
|
1449
|
+
return new Error(
|
|
1450
|
+
[
|
|
1451
|
+
"Invalid APOA grant input.",
|
|
1452
|
+
...errors.map((error) => `- ${error}`),
|
|
1453
|
+
"Minimal shape: { principal, agent, service, scopes, expiresIn }"
|
|
1454
|
+
].join("\n")
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1285
1457
|
export {
|
|
1458
|
+
APOA,
|
|
1286
1459
|
APOAError,
|
|
1287
1460
|
AttenuationViolationError,
|
|
1288
1461
|
ChainVerificationError,
|
|
@@ -1307,6 +1480,7 @@ export {
|
|
|
1307
1480
|
generateKeyPair2 as generateKeyPair,
|
|
1308
1481
|
getAuditTrail,
|
|
1309
1482
|
getAuditTrailByService,
|
|
1483
|
+
getDelegationAncestorIds,
|
|
1310
1484
|
isBeforeNotBefore,
|
|
1311
1485
|
isExpired,
|
|
1312
1486
|
isRevoked,
|