@canton-network/core-wallet-auth 0.22.0 → 0.23.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/dist/auth-service.d.ts +2 -2
- package/dist/auth-service.d.ts.map +1 -1
- package/dist/auth-token-provider.d.ts +45 -9
- package/dist/auth-token-provider.d.ts.map +1 -1
- package/dist/auth-utils.d.ts +14 -0
- package/dist/auth-utils.d.ts.map +1 -1
- package/dist/index.cjs +144 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +143 -136
- package/dist/index.js.map +1 -1
- package/dist/self-signed-token-service.d.ts +6 -0
- package/dist/self-signed-token-service.d.ts.map +1 -0
- package/package.json +3 -3
- package/dist/auth-token-provider-self-signed.d.ts +0 -14
- package/dist/auth-token-provider-self-signed.d.ts.map +0 -1
package/dist/auth-service.d.ts
CHANGED
|
@@ -23,8 +23,8 @@ export interface AuthService {
|
|
|
23
23
|
* Interface for providing access tokens used to authenticate requests
|
|
24
24
|
*/
|
|
25
25
|
export interface AccessTokenProvider {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
getAccessToken(): Promise<string>;
|
|
27
|
+
getAuthContext(): Promise<AuthContext>;
|
|
28
28
|
}
|
|
29
29
|
export interface OIDCConfig {
|
|
30
30
|
token_endpoint: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../src/auth-service.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,MAAM,GAAG,MAAM,CAAA;AAE3B;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IACxB,WAAW,EAAE,WAAW,GAAG,SAAS,CAAA;IACpC,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,CAAC,CAAA;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAA;CACtE;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,
|
|
1
|
+
{"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../src/auth-service.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,MAAM,GAAG,MAAM,CAAA;AAE3B;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IACxB,WAAW,EAAE,WAAW,GAAG,SAAS,CAAA;IACpC,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,CAAC,CAAA;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAA;CACtE;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACjC,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,UAAU;IACvB,cAAc,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CAC/B"}
|
|
@@ -1,13 +1,49 @@
|
|
|
1
1
|
import { Logger } from '@canton-network/core-types';
|
|
2
|
-
import { AccessTokenProvider } from './auth-service
|
|
3
|
-
import { Auth, Idp } from './config/schema
|
|
2
|
+
import { AccessTokenProvider, AuthContext, ClientCredentials } from './auth-service';
|
|
3
|
+
import { Auth, Idp } from './config/schema';
|
|
4
|
+
type TokenProviderConfig = {
|
|
5
|
+
method: 'static';
|
|
6
|
+
token: string;
|
|
7
|
+
} | {
|
|
8
|
+
method: 'self_signed';
|
|
9
|
+
issuer: string;
|
|
10
|
+
credentials: ClientCredentials;
|
|
11
|
+
} | {
|
|
12
|
+
method: 'client_credentials';
|
|
13
|
+
configUrl: string;
|
|
14
|
+
credentials: ClientCredentials;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* AuthTokenProvider provides some common functionality across token providers.
|
|
18
|
+
*
|
|
19
|
+
* 1. Token caching: tokens are cached in-memory, so long as the token lifespan is not expired.
|
|
20
|
+
* 2. Context retrieval: deriving a user context from the stored access token.
|
|
21
|
+
*
|
|
22
|
+
*
|
|
23
|
+
* The following programmatic methods of token fetching are supported:
|
|
24
|
+
*
|
|
25
|
+
* - `static`: a fixed, in-memory token. Only used for compatibility, it will totally break for expired tokens.
|
|
26
|
+
* - `self_signed`: only for development purposes, used for Canton setups that accept HMAC256 self signed tokens.
|
|
27
|
+
* - `client_credentials`: used to programmatically acquire tokens via oauth2, a.k.a "machine-to-machine" tokens.
|
|
28
|
+
*/
|
|
4
29
|
export declare class AuthTokenProvider implements AccessTokenProvider {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
30
|
+
protected readonly config: TokenProviderConfig;
|
|
31
|
+
protected logger: Logger;
|
|
32
|
+
private cachedToken;
|
|
33
|
+
constructor(config: TokenProviderConfig, logger: Logger);
|
|
34
|
+
static fromToken(token: string, logger: Logger): AuthTokenProvider;
|
|
35
|
+
static fromGatewayConfig(idp: Idp, auth: Auth, logger: Logger): AuthTokenProvider;
|
|
36
|
+
private _fetchToken;
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
* @returns A valid JWT token retrieved according to the auth configuration given.
|
|
40
|
+
*/
|
|
41
|
+
getAccessToken(): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @returns An AuthContext containing a valid token and userId.
|
|
45
|
+
*/
|
|
46
|
+
getAuthContext(): Promise<AuthContext>;
|
|
12
47
|
}
|
|
48
|
+
export {};
|
|
13
49
|
//# sourceMappingURL=auth-token-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-token-provider.d.ts","sourceRoot":"","sources":["../src/auth-token-provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACnD,OAAO,
|
|
1
|
+
{"version":3,"file":"auth-token-provider.d.ts","sourceRoot":"","sources":["../src/auth-token-provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACnD,OAAO,EACH,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACpB,MAAM,gBAAgB,CAAA;AAIvB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAE3C,KAAK,mBAAmB,GAClB;IACI,MAAM,EAAE,QAAQ,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;CAChB,GACD;IACI,MAAM,EAAE,aAAa,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,iBAAiB,CAAA;CACjC,GACD;IACI,MAAM,EAAE,oBAAoB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,iBAAiB,CAAA;CACjC,CAAA;AAEP;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAkB,YAAW,mBAAmB;IAIrD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,mBAAmB;IAC9C,SAAS,CAAC,MAAM,EAAE,MAAM;IAJ5B,OAAO,CAAC,WAAW,CAAoB;gBAGhB,MAAM,EAAE,mBAAmB,EACpC,MAAM,EAAE,MAAM;IAG5B,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAIlE,MAAM,CAAC,iBAAiB,CACpB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACf,iBAAiB;YA4CN,WAAW;IAoBzB;;;OAGG;IACU,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAgB9C;;;OAGG;IACU,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;CAMtD"}
|
package/dist/auth-utils.d.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
1
|
import { AuthContext } from './auth-service';
|
|
2
2
|
export declare function assertConnected(authContext: AuthContext | undefined): AuthContext;
|
|
3
|
+
/**
|
|
4
|
+
* Extract a User ID from the `sub` claim of a JWT. Throws if `sub` is missing.
|
|
5
|
+
*
|
|
6
|
+
* @param token a base64 encoded JWT token
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export declare function jwtUserId(token: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Determine if a given JWT is still valid based on its expiry time.
|
|
12
|
+
*
|
|
13
|
+
* @param token a base64 encoded JWT token
|
|
14
|
+
* @returns true if the token is expired, false if not
|
|
15
|
+
*/
|
|
16
|
+
export declare function jwtExpired(token: string): boolean;
|
|
3
17
|
//# sourceMappingURL=auth-utils.d.ts.map
|
package/dist/auth-utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-utils.d.ts","sourceRoot":"","sources":["../src/auth-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth-utils.d.ts","sourceRoot":"","sources":["../src/auth-utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG5C,wBAAgB,eAAe,CAC3B,WAAW,EAAE,WAAW,GAAG,SAAS,GACrC,WAAW,CAOb;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ/C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAQjD"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var jose = require('jose');
|
|
3
4
|
var coreRpcErrors = require('@canton-network/core-rpc-errors');
|
|
4
5
|
var zod = require('zod');
|
|
5
|
-
|
|
6
|
+
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
|
|
10
|
+
function assertConnected(authContext) {
|
|
11
|
+
if (!authContext) {
|
|
12
|
+
throw coreRpcErrors.providerErrors.unauthorized({
|
|
13
|
+
message: "User is not connected"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return authContext;
|
|
17
|
+
}
|
|
18
|
+
function jwtUserId(token) {
|
|
19
|
+
const { sub } = jose.decodeJwt(token);
|
|
20
|
+
if (!sub) {
|
|
21
|
+
throw new Error("token did not contain a subject field");
|
|
22
|
+
}
|
|
23
|
+
return sub;
|
|
24
|
+
}
|
|
25
|
+
function jwtExpired(token) {
|
|
26
|
+
try {
|
|
27
|
+
const payload = jose.decodeJwt(token);
|
|
28
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
29
|
+
return typeof payload.exp === "number" && payload.exp <= now;
|
|
30
|
+
} catch {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
6
34
|
|
|
7
35
|
// src/client-credentials-service.ts
|
|
8
36
|
var ClientCredentialsService = class {
|
|
@@ -80,14 +108,120 @@ var ClientCredentialsService = class {
|
|
|
80
108
|
var clientCredentialsService = (configUrl, logger) => ({
|
|
81
109
|
fetchToken: async (credentials) => new ClientCredentialsService(configUrl, logger).fetchToken(credentials)
|
|
82
110
|
});
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
111
|
+
var SelfSignedTokenService = class {
|
|
112
|
+
static async fetchToken(logger, credentials, issuer, expirySeconds = 3600) {
|
|
113
|
+
const secret = new TextEncoder().encode(credentials.clientSecret);
|
|
114
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
115
|
+
const jwt = await new jose.SignJWT({
|
|
116
|
+
sub: credentials.clientId,
|
|
117
|
+
aud: credentials.audience || "",
|
|
118
|
+
scope: credentials.scope || "",
|
|
119
|
+
iat: now,
|
|
120
|
+
exp: now + expirySeconds,
|
|
121
|
+
iss: issuer
|
|
122
|
+
}).setProtectedHeader({ alg: "HS256" }).sign(secret);
|
|
123
|
+
logger.info(`Generated self-signed JWT token: ${jwt}`);
|
|
124
|
+
return jwt;
|
|
88
125
|
}
|
|
89
|
-
|
|
90
|
-
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// src/auth-token-provider.ts
|
|
129
|
+
var AuthTokenProvider = class _AuthTokenProvider {
|
|
130
|
+
constructor(config, logger) {
|
|
131
|
+
this.config = config;
|
|
132
|
+
this.logger = logger;
|
|
133
|
+
__publicField(this, "cachedToken");
|
|
134
|
+
}
|
|
135
|
+
static fromToken(token, logger) {
|
|
136
|
+
return new _AuthTokenProvider({ method: "static", token }, logger);
|
|
137
|
+
}
|
|
138
|
+
static fromGatewayConfig(idp, auth, logger) {
|
|
139
|
+
if (auth.method === "self_signed") {
|
|
140
|
+
return new _AuthTokenProvider(
|
|
141
|
+
{
|
|
142
|
+
method: auth.method,
|
|
143
|
+
issuer: auth.issuer,
|
|
144
|
+
credentials: {
|
|
145
|
+
clientId: auth.clientId,
|
|
146
|
+
clientSecret: auth.clientSecret,
|
|
147
|
+
scope: auth.scope,
|
|
148
|
+
audience: auth.audience
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
logger
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
if (auth.method === "client_credentials") {
|
|
155
|
+
if (idp.type === "oauth")
|
|
156
|
+
return new _AuthTokenProvider(
|
|
157
|
+
{
|
|
158
|
+
method: auth.method,
|
|
159
|
+
configUrl: idp.configUrl,
|
|
160
|
+
credentials: {
|
|
161
|
+
clientId: auth.clientId,
|
|
162
|
+
clientSecret: auth.clientSecret,
|
|
163
|
+
scope: auth.scope,
|
|
164
|
+
audience: auth.audience
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
logger
|
|
168
|
+
);
|
|
169
|
+
else {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`IDP type ${idp.type} not supported for client_credentials auth`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
throw new Error(
|
|
176
|
+
`Auth method ${auth.method} not supported for programmatic access token`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
async _fetchToken() {
|
|
180
|
+
this.logger.debug("Fetching user auth token");
|
|
181
|
+
switch (this.config.method) {
|
|
182
|
+
case "static":
|
|
183
|
+
return this.config.token;
|
|
184
|
+
case "self_signed":
|
|
185
|
+
return SelfSignedTokenService.fetchToken(
|
|
186
|
+
this.logger,
|
|
187
|
+
this.config.credentials,
|
|
188
|
+
this.config.issuer
|
|
189
|
+
);
|
|
190
|
+
case "client_credentials":
|
|
191
|
+
return clientCredentialsService(
|
|
192
|
+
this.config.configUrl,
|
|
193
|
+
this.logger
|
|
194
|
+
).fetchToken(this.config.credentials);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
*
|
|
199
|
+
* @returns A valid JWT token retrieved according to the auth configuration given.
|
|
200
|
+
*/
|
|
201
|
+
async getAccessToken() {
|
|
202
|
+
if (this.cachedToken && !jwtExpired(this.cachedToken)) {
|
|
203
|
+
return this.cachedToken;
|
|
204
|
+
} else {
|
|
205
|
+
const newToken = await this._fetchToken();
|
|
206
|
+
if (jwtExpired(newToken)) {
|
|
207
|
+
throw new Error(
|
|
208
|
+
"Attempted to refresh a token, but it came back expired."
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
this.cachedToken = newToken;
|
|
212
|
+
return newToken;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
*
|
|
217
|
+
* @returns An AuthContext containing a valid token and userId.
|
|
218
|
+
*/
|
|
219
|
+
async getAuthContext() {
|
|
220
|
+
const accessToken = await this.getAccessToken();
|
|
221
|
+
const userId = jwtUserId(accessToken);
|
|
222
|
+
return { accessToken, userId };
|
|
223
|
+
}
|
|
224
|
+
};
|
|
91
225
|
var authorizationCodeAuthSchema = zod.z.object({
|
|
92
226
|
method: zod.z.literal("authorization_code"),
|
|
93
227
|
audience: zod.z.string(),
|
|
@@ -127,140 +261,14 @@ var idpSchema = zod.z.discriminatedUnion("type", [
|
|
|
127
261
|
configUrl: zod.z.string().url()
|
|
128
262
|
})
|
|
129
263
|
]);
|
|
130
|
-
var AuthTokenProviderSelfSigned = class _AuthTokenProviderSelfSigned {
|
|
131
|
-
constructor(auth, authAdmin, logger, expirySeconds = 3600) {
|
|
132
|
-
this.auth = auth;
|
|
133
|
-
this.authAdmin = authAdmin;
|
|
134
|
-
this.logger = logger;
|
|
135
|
-
this.expirySeconds = expirySeconds;
|
|
136
|
-
}
|
|
137
|
-
async getUserAccessToken() {
|
|
138
|
-
this.logger.debug("Fetching self-signed user auth token");
|
|
139
|
-
return _AuthTokenProviderSelfSigned.fetchToken(
|
|
140
|
-
this.logger,
|
|
141
|
-
{
|
|
142
|
-
clientId: this.auth.clientId,
|
|
143
|
-
clientSecret: this.auth.clientSecret,
|
|
144
|
-
scope: this.auth.scope,
|
|
145
|
-
audience: this.auth.audience
|
|
146
|
-
},
|
|
147
|
-
this.auth.issuer,
|
|
148
|
-
this.expirySeconds
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
async getAdminAccessToken() {
|
|
152
|
-
this.logger.debug("Fetching self-signed admin auth token");
|
|
153
|
-
if (!this.authAdmin) {
|
|
154
|
-
throw new Error("Admin credentials are not configured");
|
|
155
|
-
}
|
|
156
|
-
return _AuthTokenProviderSelfSigned.fetchToken(
|
|
157
|
-
this.logger,
|
|
158
|
-
{
|
|
159
|
-
clientId: this.authAdmin.clientId,
|
|
160
|
-
clientSecret: this.authAdmin.clientSecret,
|
|
161
|
-
scope: this.authAdmin.scope,
|
|
162
|
-
audience: this.authAdmin.audience
|
|
163
|
-
},
|
|
164
|
-
this.authAdmin.issuer,
|
|
165
|
-
this.expirySeconds
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
static async fetchToken(logger, credentials, issuer, expirySeconds = 3600) {
|
|
169
|
-
const secret = new TextEncoder().encode(credentials.clientSecret);
|
|
170
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
171
|
-
const jwt = await new jose.SignJWT({
|
|
172
|
-
sub: credentials.clientId,
|
|
173
|
-
aud: credentials.audience || "",
|
|
174
|
-
scope: credentials.scope || "",
|
|
175
|
-
iat: now,
|
|
176
|
-
exp: now + expirySeconds,
|
|
177
|
-
iss: issuer
|
|
178
|
-
}).setProtectedHeader({ alg: "HS256" }).sign(secret);
|
|
179
|
-
logger.info(`Generated self-signed JWT token: ${jwt}`);
|
|
180
|
-
return jwt;
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
// src/auth-token-provider.ts
|
|
185
|
-
var AuthTokenProvider = class {
|
|
186
|
-
constructor(idp, auth, adminAuth, logger) {
|
|
187
|
-
this.idp = idp;
|
|
188
|
-
this.auth = auth;
|
|
189
|
-
this.adminAuth = adminAuth;
|
|
190
|
-
this.logger = logger;
|
|
191
|
-
}
|
|
192
|
-
async getUserAccessToken() {
|
|
193
|
-
this.logger.debug("Fetching user auth token");
|
|
194
|
-
if (this.auth.method === "self_signed")
|
|
195
|
-
return new AuthTokenProviderSelfSigned(
|
|
196
|
-
this.auth,
|
|
197
|
-
this.adminAuth,
|
|
198
|
-
this.logger
|
|
199
|
-
).getUserAccessToken();
|
|
200
|
-
if (this.auth.method === "client_credentials") {
|
|
201
|
-
if (this.idp.type === "oauth")
|
|
202
|
-
return clientCredentialsService(
|
|
203
|
-
this.idp.configUrl,
|
|
204
|
-
this.logger
|
|
205
|
-
).fetchToken({
|
|
206
|
-
clientId: this.auth.clientId,
|
|
207
|
-
clientSecret: this.auth.clientSecret,
|
|
208
|
-
scope: this.auth.scope,
|
|
209
|
-
audience: this.auth.audience
|
|
210
|
-
});
|
|
211
|
-
else {
|
|
212
|
-
throw new Error(
|
|
213
|
-
`IDP type ${this.idp.type} not supported for client_credentials auth`
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
throw new Error(
|
|
218
|
-
`Auth method ${this.auth.method} not supported for user access token`
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
async getAdminAccessToken() {
|
|
222
|
-
this.logger.debug("Fetching admin auth token");
|
|
223
|
-
if (this.adminAuth.method === "self_signed")
|
|
224
|
-
return new AuthTokenProviderSelfSigned(
|
|
225
|
-
this.auth,
|
|
226
|
-
this.adminAuth,
|
|
227
|
-
this.logger
|
|
228
|
-
).getAdminAccessToken();
|
|
229
|
-
if (!this.adminAuth) {
|
|
230
|
-
throw new Error(
|
|
231
|
-
`No admin credentials configured for auth type ${this.auth.method}`
|
|
232
|
-
);
|
|
233
|
-
}
|
|
234
|
-
if (this.adminAuth.method === "client_credentials") {
|
|
235
|
-
if (this.idp.type === "oauth")
|
|
236
|
-
return clientCredentialsService(
|
|
237
|
-
this.idp.configUrl,
|
|
238
|
-
this.logger
|
|
239
|
-
).fetchToken({
|
|
240
|
-
clientId: this.adminAuth.clientId,
|
|
241
|
-
clientSecret: this.adminAuth.clientSecret,
|
|
242
|
-
scope: this.adminAuth.scope,
|
|
243
|
-
audience: this.adminAuth.audience
|
|
244
|
-
});
|
|
245
|
-
else {
|
|
246
|
-
throw new Error(
|
|
247
|
-
`IDP type ${this.idp.type} not supported for client_credentials auth`
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
} else {
|
|
251
|
-
throw new Error(
|
|
252
|
-
`Auth method ${this.auth.method} not supported for admin access token`
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
264
|
|
|
258
265
|
exports.AuthTokenProvider = AuthTokenProvider;
|
|
259
|
-
exports.AuthTokenProviderSelfSigned = AuthTokenProviderSelfSigned;
|
|
260
266
|
exports.ClientCredentialsService = ClientCredentialsService;
|
|
261
267
|
exports.assertConnected = assertConnected;
|
|
262
268
|
exports.authSchema = authSchema;
|
|
263
269
|
exports.clientCredentialsService = clientCredentialsService;
|
|
264
270
|
exports.idpSchema = idpSchema;
|
|
271
|
+
exports.jwtExpired = jwtExpired;
|
|
272
|
+
exports.jwtUserId = jwtUserId;
|
|
265
273
|
//# sourceMappingURL=index.cjs.map
|
|
266
274
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client-credentials-service.ts","../src/auth-utils.ts","../src/config/schema.ts","../src/auth-token-provider-self-signed.ts","../src/auth-token-provider.ts"],"names":["providerErrors","z","SignJWT"],"mappings":"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","file":"index.cjs","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { ClientCredentials, OIDCConfig } from './auth-service.js'\n\nexport class ClientCredentialsService {\n constructor(\n private configUrl: string,\n private logger: Logger | undefined\n ) {}\n\n /**\n * Fetches the JWT token (M2M) using client credentials.\n *\n * @returns The JWT access token as a string.\n * @throws If fetching the token fails or the response is invalid.\n */\n async fetchToken(credentials: ClientCredentials): Promise<string> {\n try {\n const oidcConfig = await this.getOIDCConfig(this.configUrl)\n this.logger?.debug({ oidcConfig }, 'Fetched OIDC config')\n\n const res: Response = await this.fetchTokenEndpoint(\n oidcConfig.token_endpoint,\n credentials\n )\n const json = await res.json()\n\n this.logger?.info(\n { response: json },\n `Fetched admin token for clientId: ${credentials.clientId}`\n )\n\n if (!json.access_token) {\n throw new Error('No access_token in token endpoint response')\n }\n\n return json.access_token\n } catch (error) {\n this.logger?.error({ err: error }, 'Failed to fetch admin token')\n throw error\n }\n }\n\n async fetchTokenEndpoint(\n tokenEndpoint: string,\n credentials: ClientCredentials\n ): Promise<Response> {\n const params = new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n scope: credentials.scope ?? '',\n audience: credentials.audience ?? '',\n })\n\n const res = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: params.toString(),\n })\n\n if (!res.ok) {\n this.logger?.error(\n { status: res.status, statusText: res.statusText },\n 'Token endpoint error'\n )\n throw new Error(\n `Token endpoint error: ${res.status} ${res.statusText}`\n )\n }\n\n return res\n }\n\n async getOIDCConfig(url: string): Promise<OIDCConfig> {\n const res = await fetch(url)\n if (!res.ok) {\n const text = await res.text()\n this.logger?.error(\n { status: res.status, statusText: res.statusText, body: text },\n 'Failed to fetch OIDC config'\n )\n throw new Error(\n `OIDC config error: ${res.status} ${res.statusText}`\n )\n }\n return res.json()\n }\n}\n\nexport const clientCredentialsService = (\n configUrl: string,\n logger: Logger | undefined\n) => ({\n fetchToken: async (credentials: ClientCredentials) =>\n new ClientCredentialsService(configUrl, logger).fetchToken(credentials),\n})\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { AuthContext } from './auth-service'\nimport { providerErrors } from '@canton-network/core-rpc-errors'\n\nexport function assertConnected(\n authContext: AuthContext | undefined\n): AuthContext {\n if (!authContext) {\n throw providerErrors.unauthorized({\n message: 'User is not connected',\n })\n }\n return authContext\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { z } from 'zod'\n\nconst authorizationCodeAuthSchema = z.object({\n method: z.literal('authorization_code'),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n})\n\nconst clientCredentialsAuthSchema = z.object({\n method: z.literal('client_credentials'),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n clientSecret: z.string(),\n})\n\nconst selfSignedAuthSchema = z.object({\n method: z.literal('self_signed'),\n issuer: z.string(),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n clientSecret: z.string(),\n})\n\nexport const authSchema = z.discriminatedUnion('method', [\n authorizationCodeAuthSchema,\n clientCredentialsAuthSchema,\n selfSignedAuthSchema,\n])\n\nexport type Auth = z.infer<typeof authSchema>\nexport type AuthorizationCodeAuth = z.infer<typeof authorizationCodeAuthSchema>\nexport type ClientCredentialsAuth = z.infer<typeof clientCredentialsAuthSchema>\nexport type SelfSignedAuth = z.infer<typeof selfSignedAuthSchema>\n\nexport const idpSchema = z.discriminatedUnion('type', [\n z.object({\n id: z.string(),\n type: z.literal('self_signed'),\n issuer: z.string(),\n }),\n z.object({\n id: z.string(),\n type: z.literal('oauth'),\n issuer: z.string(),\n configUrl: z.string().url(),\n }),\n])\n\nexport type Idp = z.infer<typeof idpSchema>\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider, ClientCredentials } from './auth-service.js'\nimport { SelfSignedAuth } from './config/schema.js'\nimport { SignJWT } from 'jose'\n\nexport class AuthTokenProviderSelfSigned implements AccessTokenProvider {\n constructor(\n private auth: SelfSignedAuth,\n private authAdmin: SelfSignedAuth,\n private logger: Logger,\n private expirySeconds: number = 3600\n ) {}\n\n async getUserAccessToken(): Promise<string> {\n this.logger.debug('Fetching self-signed user auth token')\n return AuthTokenProviderSelfSigned.fetchToken(\n this.logger,\n {\n clientId: this.auth.clientId,\n clientSecret: this.auth.clientSecret,\n scope: this.auth.scope,\n audience: this.auth.audience,\n },\n this.auth.issuer,\n this.expirySeconds\n )\n }\n\n async getAdminAccessToken(): Promise<string> {\n this.logger.debug('Fetching self-signed admin auth token')\n if (!this.authAdmin) {\n throw new Error('Admin credentials are not configured')\n }\n return AuthTokenProviderSelfSigned.fetchToken(\n this.logger,\n {\n clientId: this.authAdmin.clientId,\n clientSecret: this.authAdmin.clientSecret,\n scope: this.authAdmin.scope,\n audience: this.authAdmin.audience,\n },\n this.authAdmin.issuer,\n this.expirySeconds\n )\n }\n\n static async fetchToken(\n logger: Logger,\n credentials: ClientCredentials,\n issuer: string,\n expirySeconds: number = 3600\n ): Promise<string> {\n const secret = new TextEncoder().encode(credentials.clientSecret)\n const now = Math.floor(Date.now() / 1000)\n const jwt = await new SignJWT({\n sub: credentials.clientId,\n aud: credentials.audience || '',\n scope: credentials.scope || '',\n iat: now,\n exp: now + expirySeconds,\n iss: issuer,\n })\n .setProtectedHeader({ alg: 'HS256' })\n .sign(secret)\n\n logger.info(`Generated self-signed JWT token: ${jwt}`)\n return jwt\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from './auth-service.js'\nimport { Auth, Idp, SelfSignedAuth } from './config/schema.js'\nimport { AuthTokenProviderSelfSigned } from './auth-token-provider-self-signed.js'\nimport { clientCredentialsService } from './client-credentials-service.js'\n\nexport class AuthTokenProvider implements AccessTokenProvider {\n constructor(\n private idp: Idp,\n private auth: Auth,\n private adminAuth: Auth,\n private logger: Logger\n ) {}\n\n async getUserAccessToken(): Promise<string> {\n this.logger.debug('Fetching user auth token')\n if (this.auth.method === 'self_signed')\n return new AuthTokenProviderSelfSigned(\n this.auth,\n this.adminAuth as SelfSignedAuth,\n this.logger\n ).getUserAccessToken()\n\n if (this.auth.method === 'client_credentials') {\n if (this.idp.type === 'oauth')\n return clientCredentialsService(\n this.idp.configUrl,\n this.logger\n ).fetchToken({\n clientId: this.auth.clientId,\n clientSecret: this.auth.clientSecret,\n scope: this.auth.scope,\n audience: this.auth.audience,\n })\n else {\n throw new Error(\n `IDP type ${this.idp.type} not supported for client_credentials auth`\n )\n }\n }\n\n throw new Error(\n `Auth method ${this.auth.method} not supported for user access token`\n )\n }\n\n async getAdminAccessToken(): Promise<string> {\n this.logger.debug('Fetching admin auth token')\n if (this.adminAuth.method === 'self_signed')\n return new AuthTokenProviderSelfSigned(\n this.auth as SelfSignedAuth,\n this.adminAuth as SelfSignedAuth,\n this.logger\n ).getAdminAccessToken()\n\n if (!this.adminAuth) {\n throw new Error(\n `No admin credentials configured for auth type ${this.auth.method}`\n )\n }\n\n if (this.adminAuth.method === 'client_credentials') {\n if (this.idp.type === 'oauth')\n return clientCredentialsService(\n this.idp.configUrl,\n this.logger\n ).fetchToken({\n clientId: this.adminAuth.clientId,\n clientSecret: this.adminAuth.clientSecret,\n scope: this.adminAuth.scope,\n audience: this.adminAuth.audience,\n })\n else {\n throw new Error(\n `IDP type ${this.idp.type} not supported for client_credentials auth`\n )\n }\n } else {\n throw new Error(\n `Auth method ${this.auth.method} not supported for admin access token`\n )\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth-utils.ts","../src/client-credentials-service.ts","../src/self-signed-token-service.ts","../src/auth-token-provider.ts","../src/config/schema.ts"],"names":["providerErrors","decodeJwt","SignJWT","z"],"mappings":"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","file":"index.cjs","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { decodeJwt } from 'jose'\nimport { AuthContext } from './auth-service'\nimport { providerErrors } from '@canton-network/core-rpc-errors'\n\nexport function assertConnected(\n authContext: AuthContext | undefined\n): AuthContext {\n if (!authContext) {\n throw providerErrors.unauthorized({\n message: 'User is not connected',\n })\n }\n return authContext\n}\n\n/**\n * Extract a User ID from the `sub` claim of a JWT. Throws if `sub` is missing.\n *\n * @param token a base64 encoded JWT token\n * @returns\n */\nexport function jwtUserId(token: string): string {\n const { sub } = decodeJwt(token)\n\n if (!sub) {\n throw new Error('token did not contain a subject field')\n }\n\n return sub\n}\n\n/**\n * Determine if a given JWT is still valid based on its expiry time.\n *\n * @param token a base64 encoded JWT token\n * @returns true if the token is expired, false if not\n */\nexport function jwtExpired(token: string): boolean {\n try {\n const payload = decodeJwt(token)\n const now = Math.floor(Date.now() / 1000)\n return typeof payload.exp === 'number' && payload.exp <= now\n } catch {\n return true\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { ClientCredentials, OIDCConfig } from './auth-service.js'\n\nexport class ClientCredentialsService {\n constructor(\n private configUrl: string,\n private logger: Logger | undefined\n ) {}\n\n /**\n * Fetches the JWT token (M2M) using client credentials.\n *\n * @returns The JWT access token as a string.\n * @throws If fetching the token fails or the response is invalid.\n */\n async fetchToken(credentials: ClientCredentials): Promise<string> {\n try {\n const oidcConfig = await this.getOIDCConfig(this.configUrl)\n this.logger?.debug({ oidcConfig }, 'Fetched OIDC config')\n\n const res: Response = await this.fetchTokenEndpoint(\n oidcConfig.token_endpoint,\n credentials\n )\n const json = await res.json()\n\n this.logger?.info(\n { response: json },\n `Fetched admin token for clientId: ${credentials.clientId}`\n )\n\n if (!json.access_token) {\n throw new Error('No access_token in token endpoint response')\n }\n\n return json.access_token\n } catch (error) {\n this.logger?.error({ err: error }, 'Failed to fetch admin token')\n throw error\n }\n }\n\n async fetchTokenEndpoint(\n tokenEndpoint: string,\n credentials: ClientCredentials\n ): Promise<Response> {\n const params = new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n scope: credentials.scope ?? '',\n audience: credentials.audience ?? '',\n })\n\n const res = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: params.toString(),\n })\n\n if (!res.ok) {\n this.logger?.error(\n { status: res.status, statusText: res.statusText },\n 'Token endpoint error'\n )\n throw new Error(\n `Token endpoint error: ${res.status} ${res.statusText}`\n )\n }\n\n return res\n }\n\n async getOIDCConfig(url: string): Promise<OIDCConfig> {\n const res = await fetch(url)\n if (!res.ok) {\n const text = await res.text()\n this.logger?.error(\n { status: res.status, statusText: res.statusText, body: text },\n 'Failed to fetch OIDC config'\n )\n throw new Error(\n `OIDC config error: ${res.status} ${res.statusText}`\n )\n }\n return res.json()\n }\n}\n\nexport const clientCredentialsService = (\n configUrl: string,\n logger: Logger | undefined\n) => ({\n fetchToken: async (credentials: ClientCredentials) =>\n new ClientCredentialsService(configUrl, logger).fetchToken(credentials),\n})\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { ClientCredentials } from './auth-service.js'\nimport { SignJWT } from 'jose'\n\nexport class SelfSignedTokenService {\n static async fetchToken(\n logger: Logger,\n credentials: ClientCredentials,\n issuer: string,\n expirySeconds: number = 3600\n ): Promise<string> {\n const secret = new TextEncoder().encode(credentials.clientSecret)\n const now = Math.floor(Date.now() / 1000)\n const jwt = await new SignJWT({\n sub: credentials.clientId,\n aud: credentials.audience || '',\n scope: credentials.scope || '',\n iat: now,\n exp: now + expirySeconds,\n iss: issuer,\n })\n .setProtectedHeader({ alg: 'HS256' })\n .sign(secret)\n\n logger.info(`Generated self-signed JWT token: ${jwt}`)\n return jwt\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport {\n AccessTokenProvider,\n AuthContext,\n ClientCredentials,\n} from './auth-service'\nimport { jwtExpired, jwtUserId } from './auth-utils'\nimport { clientCredentialsService } from './client-credentials-service'\nimport { SelfSignedTokenService } from './self-signed-token-service'\nimport { Auth, Idp } from './config/schema'\n\ntype TokenProviderConfig =\n | {\n method: 'static'\n token: string\n }\n | {\n method: 'self_signed'\n issuer: string\n credentials: ClientCredentials\n }\n | {\n method: 'client_credentials'\n configUrl: string\n credentials: ClientCredentials\n }\n\n/**\n * AuthTokenProvider provides some common functionality across token providers.\n *\n * 1. Token caching: tokens are cached in-memory, so long as the token lifespan is not expired.\n * 2. Context retrieval: deriving a user context from the stored access token.\n *\n *\n * The following programmatic methods of token fetching are supported:\n *\n * - `static`: a fixed, in-memory token. Only used for compatibility, it will totally break for expired tokens.\n * - `self_signed`: only for development purposes, used for Canton setups that accept HMAC256 self signed tokens.\n * - `client_credentials`: used to programmatically acquire tokens via oauth2, a.k.a \"machine-to-machine\" tokens.\n */\nexport class AuthTokenProvider implements AccessTokenProvider {\n private cachedToken: string | undefined\n\n constructor(\n protected readonly config: TokenProviderConfig,\n protected logger: Logger\n ) {}\n\n static fromToken(token: string, logger: Logger): AuthTokenProvider {\n return new AuthTokenProvider({ method: 'static', token }, logger)\n }\n\n static fromGatewayConfig(\n idp: Idp,\n auth: Auth,\n logger: Logger\n ): AuthTokenProvider {\n if (auth.method === 'self_signed') {\n return new AuthTokenProvider(\n {\n method: auth.method,\n issuer: auth.issuer,\n credentials: {\n clientId: auth.clientId,\n clientSecret: auth.clientSecret,\n scope: auth.scope,\n audience: auth.audience,\n },\n },\n logger\n )\n }\n\n if (auth.method === 'client_credentials') {\n if (idp.type === 'oauth')\n return new AuthTokenProvider(\n {\n method: auth.method,\n configUrl: idp.configUrl,\n credentials: {\n clientId: auth.clientId,\n clientSecret: auth.clientSecret,\n scope: auth.scope,\n audience: auth.audience,\n },\n },\n logger\n )\n else {\n throw new Error(\n `IDP type ${idp.type} not supported for client_credentials auth`\n )\n }\n }\n\n throw new Error(\n `Auth method ${auth.method} not supported for programmatic access token`\n )\n }\n\n private async _fetchToken(): Promise<string> {\n this.logger.debug('Fetching user auth token')\n\n switch (this.config.method) {\n case 'static':\n return this.config.token\n case 'self_signed':\n return SelfSignedTokenService.fetchToken(\n this.logger,\n this.config.credentials,\n this.config.issuer\n )\n case 'client_credentials':\n return clientCredentialsService(\n this.config.configUrl,\n this.logger\n ).fetchToken(this.config.credentials)\n }\n }\n\n /**\n *\n * @returns A valid JWT token retrieved according to the auth configuration given.\n */\n public async getAccessToken(): Promise<string> {\n if (this.cachedToken && !jwtExpired(this.cachedToken)) {\n return this.cachedToken\n } else {\n const newToken = await this._fetchToken()\n if (jwtExpired(newToken)) {\n throw new Error(\n 'Attempted to refresh a token, but it came back expired.'\n )\n }\n\n this.cachedToken = newToken\n return newToken\n }\n }\n\n /**\n *\n * @returns An AuthContext containing a valid token and userId.\n */\n public async getAuthContext(): Promise<AuthContext> {\n const accessToken = await this.getAccessToken()\n const userId = jwtUserId(accessToken)\n\n return { accessToken, userId }\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { z } from 'zod'\n\nconst authorizationCodeAuthSchema = z.object({\n method: z.literal('authorization_code'),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n})\n\nconst clientCredentialsAuthSchema = z.object({\n method: z.literal('client_credentials'),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n clientSecret: z.string(),\n})\n\nconst selfSignedAuthSchema = z.object({\n method: z.literal('self_signed'),\n issuer: z.string(),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n clientSecret: z.string(),\n})\n\nexport const authSchema = z.discriminatedUnion('method', [\n authorizationCodeAuthSchema,\n clientCredentialsAuthSchema,\n selfSignedAuthSchema,\n])\n\nexport type Auth = z.infer<typeof authSchema>\nexport type AuthorizationCodeAuth = z.infer<typeof authorizationCodeAuthSchema>\nexport type ClientCredentialsAuth = z.infer<typeof clientCredentialsAuthSchema>\nexport type SelfSignedAuth = z.infer<typeof selfSignedAuthSchema>\n\nexport const idpSchema = z.discriminatedUnion('type', [\n z.object({\n id: z.string(),\n type: z.literal('self_signed'),\n issuer: z.string(),\n }),\n z.object({\n id: z.string(),\n type: z.literal('oauth'),\n issuer: z.string(),\n configUrl: z.string().url(),\n }),\n])\n\nexport type Idp = z.infer<typeof idpSchema>\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from './auth-service.js';
|
|
2
|
-
export * from './client-credentials-service.js';
|
|
3
2
|
export * from './auth-utils.js';
|
|
3
|
+
export * from './client-credentials-service.js';
|
|
4
|
+
export * from './auth-token-provider.js';
|
|
4
5
|
export * from './config/schema.js';
|
|
5
6
|
export * from './auth-token-provider.js';
|
|
6
|
-
export * from './auth-token-provider-self-signed.js';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,mBAAmB,CAAA;AACjC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iCAAiC,CAAA;AAC/C,cAAc,0BAA0B,CAAA;AACxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,0BAA0B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
|
+
import { decodeJwt, SignJWT } from 'jose';
|
|
1
2
|
import { providerErrors } from '@canton-network/core-rpc-errors';
|
|
2
3
|
import { z } from 'zod';
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
|
|
8
|
+
function assertConnected(authContext) {
|
|
9
|
+
if (!authContext) {
|
|
10
|
+
throw providerErrors.unauthorized({
|
|
11
|
+
message: "User is not connected"
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
return authContext;
|
|
15
|
+
}
|
|
16
|
+
function jwtUserId(token) {
|
|
17
|
+
const { sub } = decodeJwt(token);
|
|
18
|
+
if (!sub) {
|
|
19
|
+
throw new Error("token did not contain a subject field");
|
|
20
|
+
}
|
|
21
|
+
return sub;
|
|
22
|
+
}
|
|
23
|
+
function jwtExpired(token) {
|
|
24
|
+
try {
|
|
25
|
+
const payload = decodeJwt(token);
|
|
26
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
27
|
+
return typeof payload.exp === "number" && payload.exp <= now;
|
|
28
|
+
} catch {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
4
32
|
|
|
5
33
|
// src/client-credentials-service.ts
|
|
6
34
|
var ClientCredentialsService = class {
|
|
@@ -78,14 +106,120 @@ var ClientCredentialsService = class {
|
|
|
78
106
|
var clientCredentialsService = (configUrl, logger) => ({
|
|
79
107
|
fetchToken: async (credentials) => new ClientCredentialsService(configUrl, logger).fetchToken(credentials)
|
|
80
108
|
});
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
109
|
+
var SelfSignedTokenService = class {
|
|
110
|
+
static async fetchToken(logger, credentials, issuer, expirySeconds = 3600) {
|
|
111
|
+
const secret = new TextEncoder().encode(credentials.clientSecret);
|
|
112
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
113
|
+
const jwt = await new SignJWT({
|
|
114
|
+
sub: credentials.clientId,
|
|
115
|
+
aud: credentials.audience || "",
|
|
116
|
+
scope: credentials.scope || "",
|
|
117
|
+
iat: now,
|
|
118
|
+
exp: now + expirySeconds,
|
|
119
|
+
iss: issuer
|
|
120
|
+
}).setProtectedHeader({ alg: "HS256" }).sign(secret);
|
|
121
|
+
logger.info(`Generated self-signed JWT token: ${jwt}`);
|
|
122
|
+
return jwt;
|
|
86
123
|
}
|
|
87
|
-
|
|
88
|
-
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// src/auth-token-provider.ts
|
|
127
|
+
var AuthTokenProvider = class _AuthTokenProvider {
|
|
128
|
+
constructor(config, logger) {
|
|
129
|
+
this.config = config;
|
|
130
|
+
this.logger = logger;
|
|
131
|
+
__publicField(this, "cachedToken");
|
|
132
|
+
}
|
|
133
|
+
static fromToken(token, logger) {
|
|
134
|
+
return new _AuthTokenProvider({ method: "static", token }, logger);
|
|
135
|
+
}
|
|
136
|
+
static fromGatewayConfig(idp, auth, logger) {
|
|
137
|
+
if (auth.method === "self_signed") {
|
|
138
|
+
return new _AuthTokenProvider(
|
|
139
|
+
{
|
|
140
|
+
method: auth.method,
|
|
141
|
+
issuer: auth.issuer,
|
|
142
|
+
credentials: {
|
|
143
|
+
clientId: auth.clientId,
|
|
144
|
+
clientSecret: auth.clientSecret,
|
|
145
|
+
scope: auth.scope,
|
|
146
|
+
audience: auth.audience
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
logger
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
if (auth.method === "client_credentials") {
|
|
153
|
+
if (idp.type === "oauth")
|
|
154
|
+
return new _AuthTokenProvider(
|
|
155
|
+
{
|
|
156
|
+
method: auth.method,
|
|
157
|
+
configUrl: idp.configUrl,
|
|
158
|
+
credentials: {
|
|
159
|
+
clientId: auth.clientId,
|
|
160
|
+
clientSecret: auth.clientSecret,
|
|
161
|
+
scope: auth.scope,
|
|
162
|
+
audience: auth.audience
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
logger
|
|
166
|
+
);
|
|
167
|
+
else {
|
|
168
|
+
throw new Error(
|
|
169
|
+
`IDP type ${idp.type} not supported for client_credentials auth`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
throw new Error(
|
|
174
|
+
`Auth method ${auth.method} not supported for programmatic access token`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
async _fetchToken() {
|
|
178
|
+
this.logger.debug("Fetching user auth token");
|
|
179
|
+
switch (this.config.method) {
|
|
180
|
+
case "static":
|
|
181
|
+
return this.config.token;
|
|
182
|
+
case "self_signed":
|
|
183
|
+
return SelfSignedTokenService.fetchToken(
|
|
184
|
+
this.logger,
|
|
185
|
+
this.config.credentials,
|
|
186
|
+
this.config.issuer
|
|
187
|
+
);
|
|
188
|
+
case "client_credentials":
|
|
189
|
+
return clientCredentialsService(
|
|
190
|
+
this.config.configUrl,
|
|
191
|
+
this.logger
|
|
192
|
+
).fetchToken(this.config.credentials);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
*
|
|
197
|
+
* @returns A valid JWT token retrieved according to the auth configuration given.
|
|
198
|
+
*/
|
|
199
|
+
async getAccessToken() {
|
|
200
|
+
if (this.cachedToken && !jwtExpired(this.cachedToken)) {
|
|
201
|
+
return this.cachedToken;
|
|
202
|
+
} else {
|
|
203
|
+
const newToken = await this._fetchToken();
|
|
204
|
+
if (jwtExpired(newToken)) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
"Attempted to refresh a token, but it came back expired."
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
this.cachedToken = newToken;
|
|
210
|
+
return newToken;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
*
|
|
215
|
+
* @returns An AuthContext containing a valid token and userId.
|
|
216
|
+
*/
|
|
217
|
+
async getAuthContext() {
|
|
218
|
+
const accessToken = await this.getAccessToken();
|
|
219
|
+
const userId = jwtUserId(accessToken);
|
|
220
|
+
return { accessToken, userId };
|
|
221
|
+
}
|
|
222
|
+
};
|
|
89
223
|
var authorizationCodeAuthSchema = z.object({
|
|
90
224
|
method: z.literal("authorization_code"),
|
|
91
225
|
audience: z.string(),
|
|
@@ -125,134 +259,7 @@ var idpSchema = z.discriminatedUnion("type", [
|
|
|
125
259
|
configUrl: z.string().url()
|
|
126
260
|
})
|
|
127
261
|
]);
|
|
128
|
-
var AuthTokenProviderSelfSigned = class _AuthTokenProviderSelfSigned {
|
|
129
|
-
constructor(auth, authAdmin, logger, expirySeconds = 3600) {
|
|
130
|
-
this.auth = auth;
|
|
131
|
-
this.authAdmin = authAdmin;
|
|
132
|
-
this.logger = logger;
|
|
133
|
-
this.expirySeconds = expirySeconds;
|
|
134
|
-
}
|
|
135
|
-
async getUserAccessToken() {
|
|
136
|
-
this.logger.debug("Fetching self-signed user auth token");
|
|
137
|
-
return _AuthTokenProviderSelfSigned.fetchToken(
|
|
138
|
-
this.logger,
|
|
139
|
-
{
|
|
140
|
-
clientId: this.auth.clientId,
|
|
141
|
-
clientSecret: this.auth.clientSecret,
|
|
142
|
-
scope: this.auth.scope,
|
|
143
|
-
audience: this.auth.audience
|
|
144
|
-
},
|
|
145
|
-
this.auth.issuer,
|
|
146
|
-
this.expirySeconds
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
async getAdminAccessToken() {
|
|
150
|
-
this.logger.debug("Fetching self-signed admin auth token");
|
|
151
|
-
if (!this.authAdmin) {
|
|
152
|
-
throw new Error("Admin credentials are not configured");
|
|
153
|
-
}
|
|
154
|
-
return _AuthTokenProviderSelfSigned.fetchToken(
|
|
155
|
-
this.logger,
|
|
156
|
-
{
|
|
157
|
-
clientId: this.authAdmin.clientId,
|
|
158
|
-
clientSecret: this.authAdmin.clientSecret,
|
|
159
|
-
scope: this.authAdmin.scope,
|
|
160
|
-
audience: this.authAdmin.audience
|
|
161
|
-
},
|
|
162
|
-
this.authAdmin.issuer,
|
|
163
|
-
this.expirySeconds
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
static async fetchToken(logger, credentials, issuer, expirySeconds = 3600) {
|
|
167
|
-
const secret = new TextEncoder().encode(credentials.clientSecret);
|
|
168
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
169
|
-
const jwt = await new SignJWT({
|
|
170
|
-
sub: credentials.clientId,
|
|
171
|
-
aud: credentials.audience || "",
|
|
172
|
-
scope: credentials.scope || "",
|
|
173
|
-
iat: now,
|
|
174
|
-
exp: now + expirySeconds,
|
|
175
|
-
iss: issuer
|
|
176
|
-
}).setProtectedHeader({ alg: "HS256" }).sign(secret);
|
|
177
|
-
logger.info(`Generated self-signed JWT token: ${jwt}`);
|
|
178
|
-
return jwt;
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
// src/auth-token-provider.ts
|
|
183
|
-
var AuthTokenProvider = class {
|
|
184
|
-
constructor(idp, auth, adminAuth, logger) {
|
|
185
|
-
this.idp = idp;
|
|
186
|
-
this.auth = auth;
|
|
187
|
-
this.adminAuth = adminAuth;
|
|
188
|
-
this.logger = logger;
|
|
189
|
-
}
|
|
190
|
-
async getUserAccessToken() {
|
|
191
|
-
this.logger.debug("Fetching user auth token");
|
|
192
|
-
if (this.auth.method === "self_signed")
|
|
193
|
-
return new AuthTokenProviderSelfSigned(
|
|
194
|
-
this.auth,
|
|
195
|
-
this.adminAuth,
|
|
196
|
-
this.logger
|
|
197
|
-
).getUserAccessToken();
|
|
198
|
-
if (this.auth.method === "client_credentials") {
|
|
199
|
-
if (this.idp.type === "oauth")
|
|
200
|
-
return clientCredentialsService(
|
|
201
|
-
this.idp.configUrl,
|
|
202
|
-
this.logger
|
|
203
|
-
).fetchToken({
|
|
204
|
-
clientId: this.auth.clientId,
|
|
205
|
-
clientSecret: this.auth.clientSecret,
|
|
206
|
-
scope: this.auth.scope,
|
|
207
|
-
audience: this.auth.audience
|
|
208
|
-
});
|
|
209
|
-
else {
|
|
210
|
-
throw new Error(
|
|
211
|
-
`IDP type ${this.idp.type} not supported for client_credentials auth`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
throw new Error(
|
|
216
|
-
`Auth method ${this.auth.method} not supported for user access token`
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
async getAdminAccessToken() {
|
|
220
|
-
this.logger.debug("Fetching admin auth token");
|
|
221
|
-
if (this.adminAuth.method === "self_signed")
|
|
222
|
-
return new AuthTokenProviderSelfSigned(
|
|
223
|
-
this.auth,
|
|
224
|
-
this.adminAuth,
|
|
225
|
-
this.logger
|
|
226
|
-
).getAdminAccessToken();
|
|
227
|
-
if (!this.adminAuth) {
|
|
228
|
-
throw new Error(
|
|
229
|
-
`No admin credentials configured for auth type ${this.auth.method}`
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
if (this.adminAuth.method === "client_credentials") {
|
|
233
|
-
if (this.idp.type === "oauth")
|
|
234
|
-
return clientCredentialsService(
|
|
235
|
-
this.idp.configUrl,
|
|
236
|
-
this.logger
|
|
237
|
-
).fetchToken({
|
|
238
|
-
clientId: this.adminAuth.clientId,
|
|
239
|
-
clientSecret: this.adminAuth.clientSecret,
|
|
240
|
-
scope: this.adminAuth.scope,
|
|
241
|
-
audience: this.adminAuth.audience
|
|
242
|
-
});
|
|
243
|
-
else {
|
|
244
|
-
throw new Error(
|
|
245
|
-
`IDP type ${this.idp.type} not supported for client_credentials auth`
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
} else {
|
|
249
|
-
throw new Error(
|
|
250
|
-
`Auth method ${this.auth.method} not supported for admin access token`
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
262
|
|
|
256
|
-
export { AuthTokenProvider,
|
|
263
|
+
export { AuthTokenProvider, ClientCredentialsService, assertConnected, authSchema, clientCredentialsService, idpSchema, jwtExpired, jwtUserId };
|
|
257
264
|
//# sourceMappingURL=index.js.map
|
|
258
265
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client-credentials-service.ts","../src/auth-utils.ts","../src/config/schema.ts","../src/auth-token-provider-self-signed.ts","../src/auth-token-provider.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { ClientCredentials, OIDCConfig } from './auth-service.js'\n\nexport class ClientCredentialsService {\n constructor(\n private configUrl: string,\n private logger: Logger | undefined\n ) {}\n\n /**\n * Fetches the JWT token (M2M) using client credentials.\n *\n * @returns The JWT access token as a string.\n * @throws If fetching the token fails or the response is invalid.\n */\n async fetchToken(credentials: ClientCredentials): Promise<string> {\n try {\n const oidcConfig = await this.getOIDCConfig(this.configUrl)\n this.logger?.debug({ oidcConfig }, 'Fetched OIDC config')\n\n const res: Response = await this.fetchTokenEndpoint(\n oidcConfig.token_endpoint,\n credentials\n )\n const json = await res.json()\n\n this.logger?.info(\n { response: json },\n `Fetched admin token for clientId: ${credentials.clientId}`\n )\n\n if (!json.access_token) {\n throw new Error('No access_token in token endpoint response')\n }\n\n return json.access_token\n } catch (error) {\n this.logger?.error({ err: error }, 'Failed to fetch admin token')\n throw error\n }\n }\n\n async fetchTokenEndpoint(\n tokenEndpoint: string,\n credentials: ClientCredentials\n ): Promise<Response> {\n const params = new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n scope: credentials.scope ?? '',\n audience: credentials.audience ?? '',\n })\n\n const res = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: params.toString(),\n })\n\n if (!res.ok) {\n this.logger?.error(\n { status: res.status, statusText: res.statusText },\n 'Token endpoint error'\n )\n throw new Error(\n `Token endpoint error: ${res.status} ${res.statusText}`\n )\n }\n\n return res\n }\n\n async getOIDCConfig(url: string): Promise<OIDCConfig> {\n const res = await fetch(url)\n if (!res.ok) {\n const text = await res.text()\n this.logger?.error(\n { status: res.status, statusText: res.statusText, body: text },\n 'Failed to fetch OIDC config'\n )\n throw new Error(\n `OIDC config error: ${res.status} ${res.statusText}`\n )\n }\n return res.json()\n }\n}\n\nexport const clientCredentialsService = (\n configUrl: string,\n logger: Logger | undefined\n) => ({\n fetchToken: async (credentials: ClientCredentials) =>\n new ClientCredentialsService(configUrl, logger).fetchToken(credentials),\n})\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { AuthContext } from './auth-service'\nimport { providerErrors } from '@canton-network/core-rpc-errors'\n\nexport function assertConnected(\n authContext: AuthContext | undefined\n): AuthContext {\n if (!authContext) {\n throw providerErrors.unauthorized({\n message: 'User is not connected',\n })\n }\n return authContext\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { z } from 'zod'\n\nconst authorizationCodeAuthSchema = z.object({\n method: z.literal('authorization_code'),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n})\n\nconst clientCredentialsAuthSchema = z.object({\n method: z.literal('client_credentials'),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n clientSecret: z.string(),\n})\n\nconst selfSignedAuthSchema = z.object({\n method: z.literal('self_signed'),\n issuer: z.string(),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n clientSecret: z.string(),\n})\n\nexport const authSchema = z.discriminatedUnion('method', [\n authorizationCodeAuthSchema,\n clientCredentialsAuthSchema,\n selfSignedAuthSchema,\n])\n\nexport type Auth = z.infer<typeof authSchema>\nexport type AuthorizationCodeAuth = z.infer<typeof authorizationCodeAuthSchema>\nexport type ClientCredentialsAuth = z.infer<typeof clientCredentialsAuthSchema>\nexport type SelfSignedAuth = z.infer<typeof selfSignedAuthSchema>\n\nexport const idpSchema = z.discriminatedUnion('type', [\n z.object({\n id: z.string(),\n type: z.literal('self_signed'),\n issuer: z.string(),\n }),\n z.object({\n id: z.string(),\n type: z.literal('oauth'),\n issuer: z.string(),\n configUrl: z.string().url(),\n }),\n])\n\nexport type Idp = z.infer<typeof idpSchema>\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider, ClientCredentials } from './auth-service.js'\nimport { SelfSignedAuth } from './config/schema.js'\nimport { SignJWT } from 'jose'\n\nexport class AuthTokenProviderSelfSigned implements AccessTokenProvider {\n constructor(\n private auth: SelfSignedAuth,\n private authAdmin: SelfSignedAuth,\n private logger: Logger,\n private expirySeconds: number = 3600\n ) {}\n\n async getUserAccessToken(): Promise<string> {\n this.logger.debug('Fetching self-signed user auth token')\n return AuthTokenProviderSelfSigned.fetchToken(\n this.logger,\n {\n clientId: this.auth.clientId,\n clientSecret: this.auth.clientSecret,\n scope: this.auth.scope,\n audience: this.auth.audience,\n },\n this.auth.issuer,\n this.expirySeconds\n )\n }\n\n async getAdminAccessToken(): Promise<string> {\n this.logger.debug('Fetching self-signed admin auth token')\n if (!this.authAdmin) {\n throw new Error('Admin credentials are not configured')\n }\n return AuthTokenProviderSelfSigned.fetchToken(\n this.logger,\n {\n clientId: this.authAdmin.clientId,\n clientSecret: this.authAdmin.clientSecret,\n scope: this.authAdmin.scope,\n audience: this.authAdmin.audience,\n },\n this.authAdmin.issuer,\n this.expirySeconds\n )\n }\n\n static async fetchToken(\n logger: Logger,\n credentials: ClientCredentials,\n issuer: string,\n expirySeconds: number = 3600\n ): Promise<string> {\n const secret = new TextEncoder().encode(credentials.clientSecret)\n const now = Math.floor(Date.now() / 1000)\n const jwt = await new SignJWT({\n sub: credentials.clientId,\n aud: credentials.audience || '',\n scope: credentials.scope || '',\n iat: now,\n exp: now + expirySeconds,\n iss: issuer,\n })\n .setProtectedHeader({ alg: 'HS256' })\n .sign(secret)\n\n logger.info(`Generated self-signed JWT token: ${jwt}`)\n return jwt\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from './auth-service.js'\nimport { Auth, Idp, SelfSignedAuth } from './config/schema.js'\nimport { AuthTokenProviderSelfSigned } from './auth-token-provider-self-signed.js'\nimport { clientCredentialsService } from './client-credentials-service.js'\n\nexport class AuthTokenProvider implements AccessTokenProvider {\n constructor(\n private idp: Idp,\n private auth: Auth,\n private adminAuth: Auth,\n private logger: Logger\n ) {}\n\n async getUserAccessToken(): Promise<string> {\n this.logger.debug('Fetching user auth token')\n if (this.auth.method === 'self_signed')\n return new AuthTokenProviderSelfSigned(\n this.auth,\n this.adminAuth as SelfSignedAuth,\n this.logger\n ).getUserAccessToken()\n\n if (this.auth.method === 'client_credentials') {\n if (this.idp.type === 'oauth')\n return clientCredentialsService(\n this.idp.configUrl,\n this.logger\n ).fetchToken({\n clientId: this.auth.clientId,\n clientSecret: this.auth.clientSecret,\n scope: this.auth.scope,\n audience: this.auth.audience,\n })\n else {\n throw new Error(\n `IDP type ${this.idp.type} not supported for client_credentials auth`\n )\n }\n }\n\n throw new Error(\n `Auth method ${this.auth.method} not supported for user access token`\n )\n }\n\n async getAdminAccessToken(): Promise<string> {\n this.logger.debug('Fetching admin auth token')\n if (this.adminAuth.method === 'self_signed')\n return new AuthTokenProviderSelfSigned(\n this.auth as SelfSignedAuth,\n this.adminAuth as SelfSignedAuth,\n this.logger\n ).getAdminAccessToken()\n\n if (!this.adminAuth) {\n throw new Error(\n `No admin credentials configured for auth type ${this.auth.method}`\n )\n }\n\n if (this.adminAuth.method === 'client_credentials') {\n if (this.idp.type === 'oauth')\n return clientCredentialsService(\n this.idp.configUrl,\n this.logger\n ).fetchToken({\n clientId: this.adminAuth.clientId,\n clientSecret: this.adminAuth.clientSecret,\n scope: this.adminAuth.scope,\n audience: this.adminAuth.audience,\n })\n else {\n throw new Error(\n `IDP type ${this.idp.type} not supported for client_credentials auth`\n )\n }\n } else {\n throw new Error(\n `Auth method ${this.auth.method} not supported for admin access token`\n )\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth-utils.ts","../src/client-credentials-service.ts","../src/self-signed-token-service.ts","../src/auth-token-provider.ts","../src/config/schema.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { decodeJwt } from 'jose'\nimport { AuthContext } from './auth-service'\nimport { providerErrors } from '@canton-network/core-rpc-errors'\n\nexport function assertConnected(\n authContext: AuthContext | undefined\n): AuthContext {\n if (!authContext) {\n throw providerErrors.unauthorized({\n message: 'User is not connected',\n })\n }\n return authContext\n}\n\n/**\n * Extract a User ID from the `sub` claim of a JWT. Throws if `sub` is missing.\n *\n * @param token a base64 encoded JWT token\n * @returns\n */\nexport function jwtUserId(token: string): string {\n const { sub } = decodeJwt(token)\n\n if (!sub) {\n throw new Error('token did not contain a subject field')\n }\n\n return sub\n}\n\n/**\n * Determine if a given JWT is still valid based on its expiry time.\n *\n * @param token a base64 encoded JWT token\n * @returns true if the token is expired, false if not\n */\nexport function jwtExpired(token: string): boolean {\n try {\n const payload = decodeJwt(token)\n const now = Math.floor(Date.now() / 1000)\n return typeof payload.exp === 'number' && payload.exp <= now\n } catch {\n return true\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { ClientCredentials, OIDCConfig } from './auth-service.js'\n\nexport class ClientCredentialsService {\n constructor(\n private configUrl: string,\n private logger: Logger | undefined\n ) {}\n\n /**\n * Fetches the JWT token (M2M) using client credentials.\n *\n * @returns The JWT access token as a string.\n * @throws If fetching the token fails or the response is invalid.\n */\n async fetchToken(credentials: ClientCredentials): Promise<string> {\n try {\n const oidcConfig = await this.getOIDCConfig(this.configUrl)\n this.logger?.debug({ oidcConfig }, 'Fetched OIDC config')\n\n const res: Response = await this.fetchTokenEndpoint(\n oidcConfig.token_endpoint,\n credentials\n )\n const json = await res.json()\n\n this.logger?.info(\n { response: json },\n `Fetched admin token for clientId: ${credentials.clientId}`\n )\n\n if (!json.access_token) {\n throw new Error('No access_token in token endpoint response')\n }\n\n return json.access_token\n } catch (error) {\n this.logger?.error({ err: error }, 'Failed to fetch admin token')\n throw error\n }\n }\n\n async fetchTokenEndpoint(\n tokenEndpoint: string,\n credentials: ClientCredentials\n ): Promise<Response> {\n const params = new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n scope: credentials.scope ?? '',\n audience: credentials.audience ?? '',\n })\n\n const res = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: params.toString(),\n })\n\n if (!res.ok) {\n this.logger?.error(\n { status: res.status, statusText: res.statusText },\n 'Token endpoint error'\n )\n throw new Error(\n `Token endpoint error: ${res.status} ${res.statusText}`\n )\n }\n\n return res\n }\n\n async getOIDCConfig(url: string): Promise<OIDCConfig> {\n const res = await fetch(url)\n if (!res.ok) {\n const text = await res.text()\n this.logger?.error(\n { status: res.status, statusText: res.statusText, body: text },\n 'Failed to fetch OIDC config'\n )\n throw new Error(\n `OIDC config error: ${res.status} ${res.statusText}`\n )\n }\n return res.json()\n }\n}\n\nexport const clientCredentialsService = (\n configUrl: string,\n logger: Logger | undefined\n) => ({\n fetchToken: async (credentials: ClientCredentials) =>\n new ClientCredentialsService(configUrl, logger).fetchToken(credentials),\n})\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport { ClientCredentials } from './auth-service.js'\nimport { SignJWT } from 'jose'\n\nexport class SelfSignedTokenService {\n static async fetchToken(\n logger: Logger,\n credentials: ClientCredentials,\n issuer: string,\n expirySeconds: number = 3600\n ): Promise<string> {\n const secret = new TextEncoder().encode(credentials.clientSecret)\n const now = Math.floor(Date.now() / 1000)\n const jwt = await new SignJWT({\n sub: credentials.clientId,\n aud: credentials.audience || '',\n scope: credentials.scope || '',\n iat: now,\n exp: now + expirySeconds,\n iss: issuer,\n })\n .setProtectedHeader({ alg: 'HS256' })\n .sign(secret)\n\n logger.info(`Generated self-signed JWT token: ${jwt}`)\n return jwt\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Logger } from '@canton-network/core-types'\nimport {\n AccessTokenProvider,\n AuthContext,\n ClientCredentials,\n} from './auth-service'\nimport { jwtExpired, jwtUserId } from './auth-utils'\nimport { clientCredentialsService } from './client-credentials-service'\nimport { SelfSignedTokenService } from './self-signed-token-service'\nimport { Auth, Idp } from './config/schema'\n\ntype TokenProviderConfig =\n | {\n method: 'static'\n token: string\n }\n | {\n method: 'self_signed'\n issuer: string\n credentials: ClientCredentials\n }\n | {\n method: 'client_credentials'\n configUrl: string\n credentials: ClientCredentials\n }\n\n/**\n * AuthTokenProvider provides some common functionality across token providers.\n *\n * 1. Token caching: tokens are cached in-memory, so long as the token lifespan is not expired.\n * 2. Context retrieval: deriving a user context from the stored access token.\n *\n *\n * The following programmatic methods of token fetching are supported:\n *\n * - `static`: a fixed, in-memory token. Only used for compatibility, it will totally break for expired tokens.\n * - `self_signed`: only for development purposes, used for Canton setups that accept HMAC256 self signed tokens.\n * - `client_credentials`: used to programmatically acquire tokens via oauth2, a.k.a \"machine-to-machine\" tokens.\n */\nexport class AuthTokenProvider implements AccessTokenProvider {\n private cachedToken: string | undefined\n\n constructor(\n protected readonly config: TokenProviderConfig,\n protected logger: Logger\n ) {}\n\n static fromToken(token: string, logger: Logger): AuthTokenProvider {\n return new AuthTokenProvider({ method: 'static', token }, logger)\n }\n\n static fromGatewayConfig(\n idp: Idp,\n auth: Auth,\n logger: Logger\n ): AuthTokenProvider {\n if (auth.method === 'self_signed') {\n return new AuthTokenProvider(\n {\n method: auth.method,\n issuer: auth.issuer,\n credentials: {\n clientId: auth.clientId,\n clientSecret: auth.clientSecret,\n scope: auth.scope,\n audience: auth.audience,\n },\n },\n logger\n )\n }\n\n if (auth.method === 'client_credentials') {\n if (idp.type === 'oauth')\n return new AuthTokenProvider(\n {\n method: auth.method,\n configUrl: idp.configUrl,\n credentials: {\n clientId: auth.clientId,\n clientSecret: auth.clientSecret,\n scope: auth.scope,\n audience: auth.audience,\n },\n },\n logger\n )\n else {\n throw new Error(\n `IDP type ${idp.type} not supported for client_credentials auth`\n )\n }\n }\n\n throw new Error(\n `Auth method ${auth.method} not supported for programmatic access token`\n )\n }\n\n private async _fetchToken(): Promise<string> {\n this.logger.debug('Fetching user auth token')\n\n switch (this.config.method) {\n case 'static':\n return this.config.token\n case 'self_signed':\n return SelfSignedTokenService.fetchToken(\n this.logger,\n this.config.credentials,\n this.config.issuer\n )\n case 'client_credentials':\n return clientCredentialsService(\n this.config.configUrl,\n this.logger\n ).fetchToken(this.config.credentials)\n }\n }\n\n /**\n *\n * @returns A valid JWT token retrieved according to the auth configuration given.\n */\n public async getAccessToken(): Promise<string> {\n if (this.cachedToken && !jwtExpired(this.cachedToken)) {\n return this.cachedToken\n } else {\n const newToken = await this._fetchToken()\n if (jwtExpired(newToken)) {\n throw new Error(\n 'Attempted to refresh a token, but it came back expired.'\n )\n }\n\n this.cachedToken = newToken\n return newToken\n }\n }\n\n /**\n *\n * @returns An AuthContext containing a valid token and userId.\n */\n public async getAuthContext(): Promise<AuthContext> {\n const accessToken = await this.getAccessToken()\n const userId = jwtUserId(accessToken)\n\n return { accessToken, userId }\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { z } from 'zod'\n\nconst authorizationCodeAuthSchema = z.object({\n method: z.literal('authorization_code'),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n})\n\nconst clientCredentialsAuthSchema = z.object({\n method: z.literal('client_credentials'),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n clientSecret: z.string(),\n})\n\nconst selfSignedAuthSchema = z.object({\n method: z.literal('self_signed'),\n issuer: z.string(),\n audience: z.string(),\n scope: z.string(),\n clientId: z.string(),\n clientSecret: z.string(),\n})\n\nexport const authSchema = z.discriminatedUnion('method', [\n authorizationCodeAuthSchema,\n clientCredentialsAuthSchema,\n selfSignedAuthSchema,\n])\n\nexport type Auth = z.infer<typeof authSchema>\nexport type AuthorizationCodeAuth = z.infer<typeof authorizationCodeAuthSchema>\nexport type ClientCredentialsAuth = z.infer<typeof clientCredentialsAuthSchema>\nexport type SelfSignedAuth = z.infer<typeof selfSignedAuthSchema>\n\nexport const idpSchema = z.discriminatedUnion('type', [\n z.object({\n id: z.string(),\n type: z.literal('self_signed'),\n issuer: z.string(),\n }),\n z.object({\n id: z.string(),\n type: z.literal('oauth'),\n issuer: z.string(),\n configUrl: z.string().url(),\n }),\n])\n\nexport type Idp = z.infer<typeof idpSchema>\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Logger } from '@canton-network/core-types';
|
|
2
|
+
import { ClientCredentials } from './auth-service.js';
|
|
3
|
+
export declare class SelfSignedTokenService {
|
|
4
|
+
static fetchToken(logger: Logger, credentials: ClientCredentials, issuer: string, expirySeconds?: number): Promise<string>;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=self-signed-token-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-signed-token-service.d.ts","sourceRoot":"","sources":["../src/self-signed-token-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAGrD,qBAAa,sBAAsB;WAClB,UAAU,CACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,iBAAiB,EAC9B,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,MAAa,GAC7B,OAAO,CAAC,MAAM,CAAC;CAiBrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canton-network/core-wallet-auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Provides authentication middleware and user management for the Wallet Gateway",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"typescript": "^5.9.3"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@canton-network/core-rpc-errors": "^0.18.
|
|
40
|
-
"@canton-network/core-types": "^0.
|
|
39
|
+
"@canton-network/core-rpc-errors": "^0.18.2",
|
|
40
|
+
"@canton-network/core-types": "^0.22.1",
|
|
41
41
|
"jose": "^6.1.3",
|
|
42
42
|
"zod": "^4.3.6"
|
|
43
43
|
},
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@canton-network/core-types';
|
|
2
|
-
import { AccessTokenProvider, ClientCredentials } from './auth-service.js';
|
|
3
|
-
import { SelfSignedAuth } from './config/schema.js';
|
|
4
|
-
export declare class AuthTokenProviderSelfSigned implements AccessTokenProvider {
|
|
5
|
-
private auth;
|
|
6
|
-
private authAdmin;
|
|
7
|
-
private logger;
|
|
8
|
-
private expirySeconds;
|
|
9
|
-
constructor(auth: SelfSignedAuth, authAdmin: SelfSignedAuth, logger: Logger, expirySeconds?: number);
|
|
10
|
-
getUserAccessToken(): Promise<string>;
|
|
11
|
-
getAdminAccessToken(): Promise<string>;
|
|
12
|
-
static fetchToken(logger: Logger, credentials: ClientCredentials, issuer: string, expirySeconds?: number): Promise<string>;
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=auth-token-provider-self-signed.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-token-provider-self-signed.d.ts","sourceRoot":"","sources":["../src/auth-token-provider-self-signed.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACnD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGnD,qBAAa,2BAA4B,YAAW,mBAAmB;IAE/D,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,aAAa;gBAHb,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,cAAc,EACzB,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,MAAa;IAGlC,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IAerC,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;WAkB/B,UAAU,CACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,iBAAiB,EAC9B,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,MAAa,GAC7B,OAAO,CAAC,MAAM,CAAC;CAiBrB"}
|