@caronte-sdk/node 0.2.0 → 0.2.1
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 -34
- package/dist/adapters/apollo.cjs +9 -9
- package/dist/adapters/apollo.cjs.map +1 -1
- package/dist/adapters/apollo.d.cts +10 -10
- package/dist/adapters/apollo.d.ts +10 -10
- package/dist/adapters/apollo.js +8 -8
- package/dist/adapters/apollo.js.map +1 -1
- package/dist/adapters/express.cjs +5 -5
- package/dist/adapters/express.cjs.map +1 -1
- package/dist/adapters/express.d.cts +6 -6
- package/dist/adapters/express.d.ts +6 -6
- package/dist/adapters/express.js +5 -5
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/fastify.cjs +9 -9
- package/dist/adapters/fastify.cjs.map +1 -1
- package/dist/adapters/fastify.d.cts +7 -7
- package/dist/adapters/fastify.d.ts +7 -7
- package/dist/adapters/fastify.js +9 -9
- package/dist/adapters/fastify.js.map +1 -1
- package/dist/adapters/nest/index.cjs +38 -38
- package/dist/adapters/nest/index.cjs.map +1 -1
- package/dist/adapters/nest/index.d.cts +15 -15
- package/dist/adapters/nest/index.d.ts +15 -15
- package/dist/adapters/nest/index.js +24 -24
- package/dist/adapters/nest/index.js.map +1 -1
- package/dist/chunk-VEDVQOBD.js +21 -0
- package/dist/chunk-VEDVQOBD.js.map +1 -0
- package/dist/{chunk-G73YTEJQ.js → chunk-XMA2NAR7.js} +15 -15
- package/dist/chunk-XMA2NAR7.js.map +1 -0
- package/dist/{client-Cgm1csuM.d.cts → client-TcOSwgrn.d.cts} +5 -5
- package/dist/{client-Cgm1csuM.d.ts → client-TcOSwgrn.d.ts} +5 -5
- package/dist/index.cjs +24 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-AKUM2UEO.js +0 -21
- package/dist/chunk-AKUM2UEO.js.map +0 -1
- package/dist/chunk-G73YTEJQ.js.map +0 -1
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
import { CanActivate, ExecutionContext, DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { Reflector } from '@nestjs/core';
|
|
3
|
-
import {
|
|
3
|
+
import { C as CaronteClient, a as CaronteClientOptions } from '../../client-TcOSwgrn.js';
|
|
4
4
|
|
|
5
|
-
declare const OPERATION_KEY = "
|
|
5
|
+
declare const OPERATION_KEY = "caronte:operation";
|
|
6
6
|
interface OperationMeta {
|
|
7
7
|
id: string;
|
|
8
8
|
level: string;
|
|
9
9
|
method: string;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Marks a controller method as a
|
|
12
|
+
* Marks a controller method as a caronte operation.
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```ts
|
|
16
16
|
* @Get()
|
|
17
17
|
* @Operation('tasks:list', 'private')
|
|
18
|
-
* listTasks(@
|
|
18
|
+
* listTasks(@CaronteUser() user: TokenClaims) { ... }
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
declare function Operation(id: string, level: string, method?: string): MethodDecorator;
|
|
22
22
|
/** Injects the authenticated user's TokenClaims into a parameter. */
|
|
23
|
-
declare const
|
|
23
|
+
declare const CaronteUser: (...dataOrPipes: unknown[]) => ParameterDecorator;
|
|
24
24
|
|
|
25
|
-
declare class
|
|
25
|
+
declare class CaronteGuard implements CanActivate {
|
|
26
26
|
private readonly client;
|
|
27
27
|
private readonly reflector;
|
|
28
|
-
constructor(client:
|
|
28
|
+
constructor(client: CaronteClient, reflector: Reflector);
|
|
29
29
|
canActivate(ctx: ExecutionContext): Promise<boolean>;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
interface
|
|
32
|
+
interface CaronteModuleOptions extends CaronteClientOptions {
|
|
33
33
|
}
|
|
34
|
-
declare class
|
|
34
|
+
declare class CaronteModule {
|
|
35
35
|
/**
|
|
36
|
-
* Register the
|
|
36
|
+
* Register the caronte module globally.
|
|
37
37
|
*
|
|
38
|
-
* Creates the `
|
|
39
|
-
* and provides `
|
|
38
|
+
* Creates the `CaronteClient`, bootstraps it (authenticate + sync + fetch),
|
|
39
|
+
* and provides `CaronteGuard` for injection.
|
|
40
40
|
*
|
|
41
41
|
* @example
|
|
42
42
|
* ```ts
|
|
43
43
|
* // app.module.ts
|
|
44
44
|
* @Module({
|
|
45
45
|
* imports: [
|
|
46
|
-
*
|
|
46
|
+
* CaronteModule.forRootAsync({
|
|
47
47
|
* authorizerUrl: process.env.AUTHORIZER_URL!,
|
|
48
48
|
* realmId: process.env.REALM_ID!,
|
|
49
49
|
* appId: process.env.APP_ID!,
|
|
@@ -54,7 +54,7 @@ declare class ArgosModule {
|
|
|
54
54
|
* export class AppModule {}
|
|
55
55
|
* ```
|
|
56
56
|
*/
|
|
57
|
-
static forRootAsync(options:
|
|
57
|
+
static forRootAsync(options: CaronteModuleOptions): DynamicModule;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export {
|
|
60
|
+
export { CaronteGuard, CaronteModule, type CaronteModuleOptions, CaronteUser, OPERATION_KEY, Operation, type OperationMeta };
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import '../../chunk-
|
|
1
|
+
import { CaronteClient } from '../../chunk-XMA2NAR7.js';
|
|
2
|
+
import '../../chunk-VEDVQOBD.js';
|
|
3
3
|
import { __decorateClass, __decorateParam, getRegistry, detectMethod, registerOperation } from '../../chunk-HV6X5RJY.js';
|
|
4
4
|
import { createParamDecorator, Injectable, Inject, Module, UnauthorizedException, ForbiddenException, SetMetadata } from '@nestjs/common';
|
|
5
5
|
import { Reflector } from '@nestjs/core';
|
|
6
6
|
|
|
7
|
-
var OPERATION_KEY = "
|
|
7
|
+
var OPERATION_KEY = "caronte:operation";
|
|
8
8
|
function Operation(id, level, method) {
|
|
9
9
|
const resolvedMethod = method ?? detectMethod(id);
|
|
10
10
|
registerOperation({ identifier: id, method: resolvedMethod, level });
|
|
11
11
|
return SetMetadata(OPERATION_KEY, { id, level, method: resolvedMethod });
|
|
12
12
|
}
|
|
13
|
-
var
|
|
14
|
-
(_data, ctx) => ctx.switchToHttp().getRequest().
|
|
13
|
+
var CaronteUser = createParamDecorator(
|
|
14
|
+
(_data, ctx) => ctx.switchToHttp().getRequest().caronteUser
|
|
15
15
|
);
|
|
16
|
-
var
|
|
16
|
+
var CaronteGuard = class {
|
|
17
17
|
// @Inject() explícito -- não depender de emitDecoratorMetadata (design:paramtypes)
|
|
18
18
|
// pra resolver os parâmetros: o build desta lib usa tsup/esbuild, que não emite
|
|
19
19
|
// essa metadata (limitação conhecida do esbuild), então a injeção implícita por
|
|
20
20
|
// tipo do Nest falha silenciosamente (reflector fica undefined em runtime,
|
|
21
|
-
// TypeError em qualquer rota guardada por
|
|
21
|
+
// TypeError em qualquer rota guardada por CaronteGuard).
|
|
22
22
|
constructor(client, reflector) {
|
|
23
23
|
this.client = client;
|
|
24
24
|
this.reflector = reflector;
|
|
@@ -45,30 +45,30 @@ var ArgosGuard = class {
|
|
|
45
45
|
} catch {
|
|
46
46
|
throw new UnauthorizedException("Invalid token.");
|
|
47
47
|
}
|
|
48
|
-
request.
|
|
48
|
+
request.caronteUser = claims;
|
|
49
49
|
const allowed = this.client.checkPermission(claims, id, method);
|
|
50
50
|
if (!allowed) throw new ForbiddenException("Insufficient permissions.");
|
|
51
51
|
return true;
|
|
52
52
|
}
|
|
53
53
|
};
|
|
54
|
-
|
|
54
|
+
CaronteGuard = __decorateClass([
|
|
55
55
|
Injectable(),
|
|
56
|
-
__decorateParam(0, Inject(
|
|
56
|
+
__decorateParam(0, Inject(CaronteClient)),
|
|
57
57
|
__decorateParam(1, Inject(Reflector))
|
|
58
|
-
],
|
|
59
|
-
var
|
|
58
|
+
], CaronteGuard);
|
|
59
|
+
var CaronteModule = class {
|
|
60
60
|
/**
|
|
61
|
-
* Register the
|
|
61
|
+
* Register the caronte module globally.
|
|
62
62
|
*
|
|
63
|
-
* Creates the `
|
|
64
|
-
* and provides `
|
|
63
|
+
* Creates the `CaronteClient`, bootstraps it (authenticate + sync + fetch),
|
|
64
|
+
* and provides `CaronteGuard` for injection.
|
|
65
65
|
*
|
|
66
66
|
* @example
|
|
67
67
|
* ```ts
|
|
68
68
|
* // app.module.ts
|
|
69
69
|
* @Module({
|
|
70
70
|
* imports: [
|
|
71
|
-
*
|
|
71
|
+
* CaronteModule.forRootAsync({
|
|
72
72
|
* authorizerUrl: process.env.AUTHORIZER_URL!,
|
|
73
73
|
* realmId: process.env.REALM_ID!,
|
|
74
74
|
* appId: process.env.APP_ID!,
|
|
@@ -81,29 +81,29 @@ var ArgosModule = class {
|
|
|
81
81
|
*/
|
|
82
82
|
static forRootAsync(options) {
|
|
83
83
|
return {
|
|
84
|
-
module:
|
|
84
|
+
module: CaronteModule,
|
|
85
85
|
global: true,
|
|
86
86
|
providers: [
|
|
87
87
|
Reflector,
|
|
88
88
|
{
|
|
89
|
-
provide:
|
|
89
|
+
provide: CaronteClient,
|
|
90
90
|
useFactory: async () => {
|
|
91
|
-
const client = new
|
|
91
|
+
const client = new CaronteClient(options);
|
|
92
92
|
for (const op of getRegistry()) client.registerOperation(op);
|
|
93
93
|
await client.startup();
|
|
94
94
|
return client;
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
|
-
|
|
97
|
+
CaronteGuard
|
|
98
98
|
],
|
|
99
|
-
exports: [
|
|
99
|
+
exports: [CaronteClient, CaronteGuard]
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
-
|
|
103
|
+
CaronteModule = __decorateClass([
|
|
104
104
|
Module({})
|
|
105
|
-
],
|
|
105
|
+
], CaronteModule);
|
|
106
106
|
|
|
107
|
-
export {
|
|
107
|
+
export { CaronteGuard, CaronteModule, CaronteUser, OPERATION_KEY, Operation };
|
|
108
108
|
//# sourceMappingURL=index.js.map
|
|
109
109
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/adapters/nest/decorator.ts","../../../src/adapters/nest/guard.ts","../../../src/adapters/nest/module.ts"],"names":["Reflector"],"mappings":";;;;;;AAIO,IAAM,aAAA,GAAgB;AAkBtB,SAAS,SAAA,CAAU,EAAA,EAAY,KAAA,EAAe,MAAA,EAAkC;AACrF,EAAA,MAAM,cAAA,GAAiB,MAAA,IAAU,YAAA,CAAa,EAAE,CAAA;AAChD,EAAA,iBAAA,CAAkB,EAAE,UAAA,EAAY,EAAA,EAAI,MAAA,EAAQ,cAAA,EAAgB,OAAO,CAAA;AACnE,EAAA,OAAO,YAAmC,aAAA,EAAe,EAAE,IAAI,KAAA,EAAO,MAAA,EAAQ,gBAAgB,CAAA;AAChG;AAGO,IAAM,
|
|
1
|
+
{"version":3,"sources":["../../../src/adapters/nest/decorator.ts","../../../src/adapters/nest/guard.ts","../../../src/adapters/nest/module.ts"],"names":["Reflector"],"mappings":"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","file":"index.js","sourcesContent":["import { createParamDecorator, ExecutionContext, SetMetadata } from '@nestjs/common';\nimport type { TokenClaims } from '../../models.js';\nimport { detectMethod, registerOperation } from '../../registry.js';\n\nexport const OPERATION_KEY = 'caronte:operation';\n\nexport interface OperationMeta {\n id: string;\n level: string;\n method: string;\n}\n\n/**\n * Marks a controller method as a caronte operation.\n *\n * @example\n * ```ts\n * @Get()\n * @Operation('tasks:list', 'private')\n * listTasks(@CaronteUser() user: TokenClaims) { ... }\n * ```\n */\nexport function Operation(id: string, level: string, method?: string): MethodDecorator {\n const resolvedMethod = method ?? detectMethod(id);\n registerOperation({ identifier: id, method: resolvedMethod, level });\n return SetMetadata<string, OperationMeta>(OPERATION_KEY, { id, level, method: resolvedMethod });\n}\n\n/** Injects the authenticated user's TokenClaims into a parameter. */\nexport const CaronteUser = createParamDecorator(\n (_data: unknown, ctx: ExecutionContext): TokenClaims | undefined =>\n ctx.switchToHttp().getRequest().caronteUser,\n);","import {\n CanActivate, ExecutionContext, ForbiddenException,\n Inject, Injectable, UnauthorizedException,\n} from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { CaronteClient } from '../../client.js';\nimport type { TokenClaims } from '../../models.js';\nimport { OPERATION_KEY, type OperationMeta } from './decorator.js';\n\n@Injectable()\nexport class CaronteGuard implements CanActivate {\n // @Inject() explícito -- não depender de emitDecoratorMetadata (design:paramtypes)\n // pra resolver os parâmetros: o build desta lib usa tsup/esbuild, que não emite\n // essa metadata (limitação conhecida do esbuild), então a injeção implícita por\n // tipo do Nest falha silenciosamente (reflector fica undefined em runtime,\n // TypeError em qualquer rota guardada por CaronteGuard).\n constructor(\n @Inject(CaronteClient) private readonly client: CaronteClient,\n @Inject(Reflector) private readonly reflector: Reflector,\n ) {}\n\n async canActivate(ctx: ExecutionContext): Promise<boolean> {\n const meta = this.reflector.get<OperationMeta | undefined>(\n OPERATION_KEY,\n ctx.getHandler(),\n );\n\n if (!meta) return true; // no @Operation — pass through\n\n const { id, level, method } = meta;\n const request = ctx.switchToHttp().getRequest<{ headers: Record<string, string>; caronteUser?: TokenClaims }>();\n\n if (level === 'public') return true;\n\n const auth = request.headers['authorization'] ?? '';\n const [scheme, token] = auth.split(' ');\n\n if (scheme?.toLowerCase() !== 'bearer' || !token) {\n throw new UnauthorizedException('Bearer token required.');\n }\n\n let claims: TokenClaims;\n try {\n claims = await this.client.validateToken(token);\n } catch {\n // Token malformado/expirado/inválido -- 401, igual aos adapters express/\n // fastify (que engolem o erro de validateToken pelo mesmo motivo), não\n // deixar virar 500 por exceção não tratada.\n throw new UnauthorizedException('Invalid token.');\n }\n request.caronteUser = claims;\n\n const allowed = this.client.checkPermission(claims, id, method);\n if (!allowed) throw new ForbiddenException('Insufficient permissions.');\n\n return true;\n }\n}","import { DynamicModule, Module } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { CaronteClient, type CaronteClientOptions } from '../../client.js';\nimport { getRegistry } from '../../registry.js';\nimport { CaronteGuard } from './guard.js';\n\nexport interface CaronteModuleOptions extends CaronteClientOptions {}\n\n@Module({})\nexport class CaronteModule {\n /**\n * Register the caronte module globally.\n *\n * Creates the `CaronteClient`, bootstraps it (authenticate + sync + fetch),\n * and provides `CaronteGuard` for injection.\n *\n * @example\n * ```ts\n * // app.module.ts\n * @Module({\n * imports: [\n * CaronteModule.forRootAsync({\n * authorizerUrl: process.env.AUTHORIZER_URL!,\n * realmId: process.env.REALM_ID!,\n * appId: process.env.APP_ID!,\n * secret: process.env.APP_SECRET!,\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\n static forRootAsync(options: CaronteModuleOptions): DynamicModule {\n return {\n module: CaronteModule,\n global: true,\n providers: [\n Reflector,\n {\n provide: CaronteClient,\n useFactory: async () => {\n const client = new CaronteClient(options);\n for (const op of getRegistry()) client.registerOperation(op);\n await client.startup();\n return client;\n },\n },\n CaronteGuard,\n ],\n exports: [CaronteClient, CaronteGuard],\n };\n }\n}"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// src/exceptions.ts
|
|
2
|
+
var CaronteError = class extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = this.constructor.name;
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
var CaronteAuthError = class extends CaronteError {
|
|
9
|
+
};
|
|
10
|
+
var CaronteTokenError = class extends CaronteError {
|
|
11
|
+
};
|
|
12
|
+
var CaronteForbiddenError = class extends CaronteError {
|
|
13
|
+
};
|
|
14
|
+
var CaronteSyncError = class extends CaronteError {
|
|
15
|
+
};
|
|
16
|
+
var CaronteConfigError = class extends CaronteError {
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { CaronteAuthError, CaronteConfigError, CaronteError, CaronteForbiddenError, CaronteSyncError, CaronteTokenError };
|
|
20
|
+
//# sourceMappingURL=chunk-VEDVQOBD.js.map
|
|
21
|
+
//# sourceMappingURL=chunk-VEDVQOBD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/exceptions.ts"],"names":[],"mappings":";AAAO,IAAM,YAAA,GAAN,cAA2B,KAAA,CAAM;AAAA,EACtC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,KAAK,WAAA,CAAY,IAAA;AAAA,EAC/B;AACF;AAEO,IAAM,gBAAA,GAAN,cAAkC,YAAA,CAAa;AAAC;AAChD,IAAM,iBAAA,GAAN,cAAkC,YAAA,CAAa;AAAC;AAChD,IAAM,qBAAA,GAAN,cAAoC,YAAA,CAAa;AAAC;AAClD,IAAM,gBAAA,GAAN,cAAkC,YAAA,CAAa;AAAC;AAChD,IAAM,kBAAA,GAAN,cAAkC,YAAA,CAAa;AAAC","file":"chunk-VEDVQOBD.js","sourcesContent":["export class CaronteError extends Error {\n constructor(message: string) {\n super(message);\n this.name = this.constructor.name;\n }\n}\n\nexport class CaronteAuthError extends CaronteError {}\nexport class CaronteTokenError extends CaronteError {}\nexport class CaronteForbiddenError extends CaronteError {}\nexport class CaronteSyncError extends CaronteError {}\nexport class CaronteConfigError extends CaronteError {}"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CaronteConfigError, CaronteAuthError, CaronteSyncError, CaronteError, CaronteTokenError } from './chunk-VEDVQOBD.js';
|
|
2
2
|
import { getRegistry } from './chunk-HV6X5RJY.js';
|
|
3
3
|
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var CaronteClient = class _CaronteClient {
|
|
6
6
|
base;
|
|
7
7
|
realmId;
|
|
8
8
|
appId;
|
|
@@ -25,7 +25,7 @@ var ArgosClient = class _ArgosClient {
|
|
|
25
25
|
}
|
|
26
26
|
async startup() {
|
|
27
27
|
if (this.registeredOperations.length === 0) {
|
|
28
|
-
throw new
|
|
28
|
+
throw new CaronteConfigError(
|
|
29
29
|
"No operations registered. Call registerOperation() before startup()."
|
|
30
30
|
);
|
|
31
31
|
}
|
|
@@ -41,12 +41,12 @@ var ArgosClient = class _ArgosClient {
|
|
|
41
41
|
body: JSON.stringify({ app_id: this.appId, secret: this.secret })
|
|
42
42
|
});
|
|
43
43
|
if (!res.ok) {
|
|
44
|
-
throw new
|
|
44
|
+
throw new CaronteAuthError(
|
|
45
45
|
`Authentication failed: HTTP ${res.status} \u2014 ${await res.text()}`
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
48
|
const data = await res.json();
|
|
49
|
-
if (!data.access_token) throw new
|
|
49
|
+
if (!data.access_token) throw new CaronteAuthError("Authorizer returned no access_token.");
|
|
50
50
|
this.appToken = data.access_token;
|
|
51
51
|
}
|
|
52
52
|
initJwks() {
|
|
@@ -72,7 +72,7 @@ var ArgosClient = class _ArgosClient {
|
|
|
72
72
|
})
|
|
73
73
|
});
|
|
74
74
|
if (!res.ok) {
|
|
75
|
-
throw new
|
|
75
|
+
throw new CaronteSyncError(`Sync failed: HTTP ${res.status} \u2014 ${await res.text()}`);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
async fetchOperations() {
|
|
@@ -81,7 +81,7 @@ var ArgosClient = class _ArgosClient {
|
|
|
81
81
|
headers: { Authorization: `Bearer ${this.appToken}` }
|
|
82
82
|
});
|
|
83
83
|
if (!res.ok) {
|
|
84
|
-
throw new
|
|
84
|
+
throw new CaronteError(
|
|
85
85
|
`Fetch operations failed: HTTP ${res.status} \u2014 ${await res.text()}`
|
|
86
86
|
);
|
|
87
87
|
}
|
|
@@ -101,7 +101,7 @@ var ArgosClient = class _ArgosClient {
|
|
|
101
101
|
const p = payload;
|
|
102
102
|
const tokenRealm = p["realm_id"] ?? "";
|
|
103
103
|
if (tokenRealm.toLowerCase() !== this.realmId.toLowerCase()) {
|
|
104
|
-
throw new
|
|
104
|
+
throw new CaronteTokenError(
|
|
105
105
|
`Token realm '${tokenRealm}' does not match this app's realm '${this.realmId}'.`
|
|
106
106
|
);
|
|
107
107
|
}
|
|
@@ -113,8 +113,8 @@ var ArgosClient = class _ArgosClient {
|
|
|
113
113
|
raw: p
|
|
114
114
|
};
|
|
115
115
|
} catch (err) {
|
|
116
|
-
if (err instanceof
|
|
117
|
-
throw new
|
|
116
|
+
if (err instanceof CaronteTokenError) throw err;
|
|
117
|
+
throw new CaronteTokenError(`Invalid token: ${err.message}`);
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
checkPermission(claims, identifier, method) {
|
|
@@ -129,18 +129,18 @@ var ArgosClient = class _ArgosClient {
|
|
|
129
129
|
}
|
|
130
130
|
/** Load operations from the global registry and bootstrap the client. */
|
|
131
131
|
static async create(options) {
|
|
132
|
-
const client = new
|
|
132
|
+
const client = new _CaronteClient(options);
|
|
133
133
|
for (const op of getRegistry()) client.registerOperation(op);
|
|
134
134
|
await client.startup();
|
|
135
135
|
return client;
|
|
136
136
|
}
|
|
137
137
|
ensureAppToken() {
|
|
138
138
|
if (!this.appToken) {
|
|
139
|
-
throw new
|
|
139
|
+
throw new CaronteAuthError("No app token. Call authenticate() or startup() first.");
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
};
|
|
143
143
|
|
|
144
|
-
export {
|
|
145
|
-
//# sourceMappingURL=chunk-
|
|
146
|
-
//# sourceMappingURL=chunk-
|
|
144
|
+
export { CaronteClient };
|
|
145
|
+
//# sourceMappingURL=chunk-XMA2NAR7.js.map
|
|
146
|
+
//# sourceMappingURL=chunk-XMA2NAR7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":"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","file":"chunk-XMA2NAR7.js","sourcesContent":["import { createRemoteJWKSet, jwtVerify, type JWTPayload } from 'jose';\nimport {\n CaronteAuthError, CaronteConfigError, CaronteError,\n CaronteSyncError, CaronteTokenError,\n} from './exceptions.js';\nimport type { OperationDescriptor, OperationWithGroups, TokenClaims } from './models.js';\nimport { getRegistry } from './registry.js';\n\nexport interface CaronteClientOptions {\n authorizerUrl: string;\n realmId: string;\n appId: string;\n secret: string;\n}\n\nexport class CaronteClient {\n private readonly base: string;\n private readonly realmId: string;\n private readonly appId: string;\n private readonly secret: string;\n\n private appToken: string | null = null;\n private jwks: ReturnType<typeof createRemoteJWKSet> | null = null;\n private operations: OperationWithGroups[] = [];\n private registeredOperations: OperationDescriptor[] = [];\n\n constructor(options: CaronteClientOptions) {\n this.base = options.authorizerUrl.replace(/\\/$/, '');\n this.realmId = options.realmId;\n this.appId = options.appId;\n this.secret = options.secret;\n }\n\n private get realmBase(): string {\n return `${this.base}/realms/${this.realmId}`;\n }\n\n registerOperation(op: OperationDescriptor): void {\n this.registeredOperations.push(op);\n }\n\n async startup(): Promise<void> {\n if (this.registeredOperations.length === 0) {\n throw new CaronteConfigError(\n 'No operations registered. Call registerOperation() before startup().',\n );\n }\n await this.authenticate();\n this.initJwks();\n await this.syncOperations();\n await this.fetchOperations();\n }\n\n async authenticate(): Promise<void> {\n const res = await fetch(`${this.realmBase}/apps/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ app_id: this.appId, secret: this.secret }),\n });\n if (!res.ok) {\n throw new CaronteAuthError(\n `Authentication failed: HTTP ${res.status} — ${await res.text()}`,\n );\n }\n const data = await res.json() as { access_token?: string };\n if (!data.access_token) throw new CaronteAuthError('Authorizer returned no access_token.');\n this.appToken = data.access_token;\n }\n\n private initJwks(): void {\n this.jwks = createRemoteJWKSet(\n new URL(`${this.realmBase}/protocol/openid-connect/certs`),\n );\n }\n\n async syncOperations(): Promise<void> {\n this.ensureAppToken();\n const res = await fetch(`${this.realmBase}/apps/operations/sync`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.appToken}`,\n },\n body: JSON.stringify({\n operations: this.registeredOperations.map(op => ({\n identifier: op.identifier,\n method: op.method,\n level: op.level,\n description: op.description ?? null,\n })),\n }),\n });\n if (!res.ok) {\n throw new CaronteSyncError(`Sync failed: HTTP ${res.status} — ${await res.text()}`);\n }\n }\n\n async fetchOperations(): Promise<void> {\n this.ensureAppToken();\n const res = await fetch(`${this.realmBase}/apps/operations`, {\n headers: { Authorization: `Bearer ${this.appToken}` },\n });\n if (!res.ok) {\n throw new CaronteError(\n `Fetch operations failed: HTTP ${res.status} — ${await res.text()}`,\n );\n }\n const data = await res.json() as { operations: any[] };\n this.operations = data.operations.map(op => ({\n operationId: op.operation_id,\n identifier: op.identifier,\n method: op.method,\n level: op.level,\n allowedGroups: op.allowed_groups ?? [],\n }));\n }\n\n async validateToken(token: string): Promise<TokenClaims> {\n if (!this.jwks) this.initJwks();\n try {\n const { payload } = await jwtVerify(token, this.jwks!);\n const p = payload as JWTPayload & Record<string, unknown>;\n const tokenRealm = (p['realm_id'] as string) ?? '';\n\n // As chaves JWKS já são buscadas em /realms/{this.realmId}/... (ver\n // realmBase), então um token de outro realm normalmente já falharia a\n // verificação de assinatura acima. Esta checagem é defesa em\n // profundidade explícita — não depende desse efeito colateral, e falha\n // com uma mensagem clara em vez de erro de assinatura.\n if (tokenRealm.toLowerCase() !== this.realmId.toLowerCase()) {\n throw new CaronteTokenError(\n `Token realm '${tokenRealm}' does not match this app's realm '${this.realmId}'.`,\n );\n }\n\n return {\n sub: payload.sub ?? '',\n realmId: tokenRealm,\n groups: (p['groups'] as string[]) ?? [],\n exp: payload.exp ?? 0,\n raw: p,\n };\n } catch (err) {\n if (err instanceof CaronteTokenError) throw err;\n throw new CaronteTokenError(`Invalid token: ${(err as Error).message}`);\n }\n }\n\n checkPermission(claims: TokenClaims, identifier: string, method: string): boolean {\n const op = this.operations.find(\n o => o.identifier === identifier && o.method === method,\n );\n if (!op) return false;\n if (op.level === 'public') return true;\n if (op.level === 'private') return claims.groups.length > 0;\n if (op.level === 'protected') return claims.groups.some(g => op.allowedGroups.includes(g));\n return false;\n }\n\n /** Load operations from the global registry and bootstrap the client. */\n static async create(options: CaronteClientOptions): Promise<CaronteClient> {\n const client = new CaronteClient(options);\n for (const op of getRegistry()) client.registerOperation(op);\n await client.startup();\n return client;\n }\n\n private ensureAppToken(): void {\n if (!this.appToken) {\n throw new CaronteAuthError('No app token. Call authenticate() or startup() first.');\n }\n }\n}"]}
|
|
@@ -16,13 +16,13 @@ interface OperationWithGroups extends OperationDescriptor {
|
|
|
16
16
|
allowedGroups: string[];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
interface
|
|
19
|
+
interface CaronteClientOptions {
|
|
20
20
|
authorizerUrl: string;
|
|
21
21
|
realmId: string;
|
|
22
22
|
appId: string;
|
|
23
23
|
secret: string;
|
|
24
24
|
}
|
|
25
|
-
declare class
|
|
25
|
+
declare class CaronteClient {
|
|
26
26
|
private readonly base;
|
|
27
27
|
private readonly realmId;
|
|
28
28
|
private readonly appId;
|
|
@@ -31,7 +31,7 @@ declare class ArgosClient {
|
|
|
31
31
|
private jwks;
|
|
32
32
|
private operations;
|
|
33
33
|
private registeredOperations;
|
|
34
|
-
constructor(options:
|
|
34
|
+
constructor(options: CaronteClientOptions);
|
|
35
35
|
private get realmBase();
|
|
36
36
|
registerOperation(op: OperationDescriptor): void;
|
|
37
37
|
startup(): Promise<void>;
|
|
@@ -42,8 +42,8 @@ declare class ArgosClient {
|
|
|
42
42
|
validateToken(token: string): Promise<TokenClaims>;
|
|
43
43
|
checkPermission(claims: TokenClaims, identifier: string, method: string): boolean;
|
|
44
44
|
/** Load operations from the global registry and bootstrap the client. */
|
|
45
|
-
static create(options:
|
|
45
|
+
static create(options: CaronteClientOptions): Promise<CaronteClient>;
|
|
46
46
|
private ensureAppToken;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export {
|
|
49
|
+
export { CaronteClient as C, type OperationDescriptor as O, type TokenClaims as T, type CaronteClientOptions as a, type OperationWithGroups as b };
|
|
@@ -16,13 +16,13 @@ interface OperationWithGroups extends OperationDescriptor {
|
|
|
16
16
|
allowedGroups: string[];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
interface
|
|
19
|
+
interface CaronteClientOptions {
|
|
20
20
|
authorizerUrl: string;
|
|
21
21
|
realmId: string;
|
|
22
22
|
appId: string;
|
|
23
23
|
secret: string;
|
|
24
24
|
}
|
|
25
|
-
declare class
|
|
25
|
+
declare class CaronteClient {
|
|
26
26
|
private readonly base;
|
|
27
27
|
private readonly realmId;
|
|
28
28
|
private readonly appId;
|
|
@@ -31,7 +31,7 @@ declare class ArgosClient {
|
|
|
31
31
|
private jwks;
|
|
32
32
|
private operations;
|
|
33
33
|
private registeredOperations;
|
|
34
|
-
constructor(options:
|
|
34
|
+
constructor(options: CaronteClientOptions);
|
|
35
35
|
private get realmBase();
|
|
36
36
|
registerOperation(op: OperationDescriptor): void;
|
|
37
37
|
startup(): Promise<void>;
|
|
@@ -42,8 +42,8 @@ declare class ArgosClient {
|
|
|
42
42
|
validateToken(token: string): Promise<TokenClaims>;
|
|
43
43
|
checkPermission(claims: TokenClaims, identifier: string, method: string): boolean;
|
|
44
44
|
/** Load operations from the global registry and bootstrap the client. */
|
|
45
|
-
static create(options:
|
|
45
|
+
static create(options: CaronteClientOptions): Promise<CaronteClient>;
|
|
46
46
|
private ensureAppToken;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export {
|
|
49
|
+
export { CaronteClient as C, type OperationDescriptor as O, type TokenClaims as T, type CaronteClientOptions as a, type OperationWithGroups as b };
|
package/dist/index.cjs
CHANGED
|
@@ -5,21 +5,21 @@ var jose = require('jose');
|
|
|
5
5
|
// src/client.ts
|
|
6
6
|
|
|
7
7
|
// src/exceptions.ts
|
|
8
|
-
var
|
|
8
|
+
var CaronteError = class extends Error {
|
|
9
9
|
constructor(message) {
|
|
10
10
|
super(message);
|
|
11
11
|
this.name = this.constructor.name;
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
|
-
var
|
|
14
|
+
var CaronteAuthError = class extends CaronteError {
|
|
15
15
|
};
|
|
16
|
-
var
|
|
16
|
+
var CaronteTokenError = class extends CaronteError {
|
|
17
17
|
};
|
|
18
|
-
var
|
|
18
|
+
var CaronteForbiddenError = class extends CaronteError {
|
|
19
19
|
};
|
|
20
|
-
var
|
|
20
|
+
var CaronteSyncError = class extends CaronteError {
|
|
21
21
|
};
|
|
22
|
-
var
|
|
22
|
+
var CaronteConfigError = class extends CaronteError {
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
// src/registry.ts
|
|
@@ -45,7 +45,7 @@ function clearRegistry() {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// src/client.ts
|
|
48
|
-
var
|
|
48
|
+
var CaronteClient = class _CaronteClient {
|
|
49
49
|
base;
|
|
50
50
|
realmId;
|
|
51
51
|
appId;
|
|
@@ -68,7 +68,7 @@ var ArgosClient = class _ArgosClient {
|
|
|
68
68
|
}
|
|
69
69
|
async startup() {
|
|
70
70
|
if (this.registeredOperations.length === 0) {
|
|
71
|
-
throw new
|
|
71
|
+
throw new CaronteConfigError(
|
|
72
72
|
"No operations registered. Call registerOperation() before startup()."
|
|
73
73
|
);
|
|
74
74
|
}
|
|
@@ -84,12 +84,12 @@ var ArgosClient = class _ArgosClient {
|
|
|
84
84
|
body: JSON.stringify({ app_id: this.appId, secret: this.secret })
|
|
85
85
|
});
|
|
86
86
|
if (!res.ok) {
|
|
87
|
-
throw new
|
|
87
|
+
throw new CaronteAuthError(
|
|
88
88
|
`Authentication failed: HTTP ${res.status} \u2014 ${await res.text()}`
|
|
89
89
|
);
|
|
90
90
|
}
|
|
91
91
|
const data = await res.json();
|
|
92
|
-
if (!data.access_token) throw new
|
|
92
|
+
if (!data.access_token) throw new CaronteAuthError("Authorizer returned no access_token.");
|
|
93
93
|
this.appToken = data.access_token;
|
|
94
94
|
}
|
|
95
95
|
initJwks() {
|
|
@@ -115,7 +115,7 @@ var ArgosClient = class _ArgosClient {
|
|
|
115
115
|
})
|
|
116
116
|
});
|
|
117
117
|
if (!res.ok) {
|
|
118
|
-
throw new
|
|
118
|
+
throw new CaronteSyncError(`Sync failed: HTTP ${res.status} \u2014 ${await res.text()}`);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
async fetchOperations() {
|
|
@@ -124,7 +124,7 @@ var ArgosClient = class _ArgosClient {
|
|
|
124
124
|
headers: { Authorization: `Bearer ${this.appToken}` }
|
|
125
125
|
});
|
|
126
126
|
if (!res.ok) {
|
|
127
|
-
throw new
|
|
127
|
+
throw new CaronteError(
|
|
128
128
|
`Fetch operations failed: HTTP ${res.status} \u2014 ${await res.text()}`
|
|
129
129
|
);
|
|
130
130
|
}
|
|
@@ -144,7 +144,7 @@ var ArgosClient = class _ArgosClient {
|
|
|
144
144
|
const p = payload;
|
|
145
145
|
const tokenRealm = p["realm_id"] ?? "";
|
|
146
146
|
if (tokenRealm.toLowerCase() !== this.realmId.toLowerCase()) {
|
|
147
|
-
throw new
|
|
147
|
+
throw new CaronteTokenError(
|
|
148
148
|
`Token realm '${tokenRealm}' does not match this app's realm '${this.realmId}'.`
|
|
149
149
|
);
|
|
150
150
|
}
|
|
@@ -156,8 +156,8 @@ var ArgosClient = class _ArgosClient {
|
|
|
156
156
|
raw: p
|
|
157
157
|
};
|
|
158
158
|
} catch (err) {
|
|
159
|
-
if (err instanceof
|
|
160
|
-
throw new
|
|
159
|
+
if (err instanceof CaronteTokenError) throw err;
|
|
160
|
+
throw new CaronteTokenError(`Invalid token: ${err.message}`);
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
checkPermission(claims, identifier, method) {
|
|
@@ -172,25 +172,25 @@ var ArgosClient = class _ArgosClient {
|
|
|
172
172
|
}
|
|
173
173
|
/** Load operations from the global registry and bootstrap the client. */
|
|
174
174
|
static async create(options) {
|
|
175
|
-
const client = new
|
|
175
|
+
const client = new _CaronteClient(options);
|
|
176
176
|
for (const op of getRegistry()) client.registerOperation(op);
|
|
177
177
|
await client.startup();
|
|
178
178
|
return client;
|
|
179
179
|
}
|
|
180
180
|
ensureAppToken() {
|
|
181
181
|
if (!this.appToken) {
|
|
182
|
-
throw new
|
|
182
|
+
throw new CaronteAuthError("No app token. Call authenticate() or startup() first.");
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
};
|
|
186
186
|
|
|
187
|
-
exports.
|
|
188
|
-
exports.
|
|
189
|
-
exports.
|
|
190
|
-
exports.
|
|
191
|
-
exports.
|
|
192
|
-
exports.
|
|
193
|
-
exports.
|
|
187
|
+
exports.CaronteAuthError = CaronteAuthError;
|
|
188
|
+
exports.CaronteClient = CaronteClient;
|
|
189
|
+
exports.CaronteConfigError = CaronteConfigError;
|
|
190
|
+
exports.CaronteError = CaronteError;
|
|
191
|
+
exports.CaronteForbiddenError = CaronteForbiddenError;
|
|
192
|
+
exports.CaronteSyncError = CaronteSyncError;
|
|
193
|
+
exports.CaronteTokenError = CaronteTokenError;
|
|
194
194
|
exports.clearRegistry = clearRegistry;
|
|
195
195
|
exports.detectMethod = detectMethod;
|
|
196
196
|
exports.getRegistry = getRegistry;
|