@canton-network/wallet-gateway-remote 1.4.0 → 1.6.0
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/jwt-auth-service.d.ts.map +1 -1
- package/dist/auth/jwt-auth-service.js +6 -5
- package/dist/auth/jwt-auth-service.test.d.ts +2 -0
- package/dist/auth/jwt-auth-service.test.d.ts.map +1 -0
- package/dist/auth/jwt-auth-service.test.js +259 -0
- package/dist/auth/jwt-unsafe-auth-service.test.d.ts +2 -0
- package/dist/auth/jwt-unsafe-auth-service.test.d.ts.map +1 -0
- package/dist/auth/jwt-unsafe-auth-service.test.js +120 -0
- package/dist/config/Config.d.ts +69 -4
- package/dist/config/Config.d.ts.map +1 -1
- package/dist/config/Config.js +6 -0
- package/dist/config/ConfigUtils.d.ts.map +1 -1
- package/dist/config/ConfigUtils.js +3 -0
- package/dist/dapp-api/controller.d.ts +5 -1
- package/dist/dapp-api/controller.d.ts.map +1 -1
- package/dist/dapp-api/controller.js +104 -30
- package/dist/dapp-api/controller.test.js +2 -2
- package/dist/dapp-api/server.d.ts +3 -2
- package/dist/dapp-api/server.d.ts.map +1 -1
- package/dist/dapp-api/server.js +2 -2
- package/dist/dapp-api/server.test.js +1 -6
- package/dist/example-config.d.ts +3 -0
- package/dist/example-config.d.ts.map +1 -1
- package/dist/example-config.js +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +19 -7
- package/dist/ledger/transaction-service.d.ts +16 -11
- package/dist/ledger/transaction-service.d.ts.map +1 -1
- package/dist/ledger/transaction-service.js +135 -8
- package/dist/ledger/transaction-service.test.d.ts +2 -0
- package/dist/ledger/transaction-service.test.d.ts.map +1 -0
- package/dist/ledger/transaction-service.test.js +390 -0
- package/dist/ledger/wallet-allocation/signing-providers/fireblocks-wallet-allocator.d.ts +5 -2
- package/dist/ledger/wallet-allocation/signing-providers/fireblocks-wallet-allocator.d.ts.map +1 -1
- package/dist/ledger/wallet-allocation/signing-providers/fireblocks-wallet-allocator.js +7 -6
- package/dist/ledger/wallet-allocation/wallet-allocation-service.d.ts +11 -5
- package/dist/ledger/wallet-allocation/wallet-allocation-service.d.ts.map +1 -1
- package/dist/ledger/wallet-allocation/wallet-allocation-service.js +28 -14
- package/dist/ledger/wallet-allocation/wallet-allocation-service.test.js +550 -19
- package/dist/ledger/wallet-sync-service.js +3 -3
- package/dist/middleware/apiKeyAuth.d.ts +6 -0
- package/dist/middleware/apiKeyAuth.d.ts.map +1 -0
- package/dist/middleware/apiKeyAuth.js +90 -0
- package/dist/middleware/apiKeyAuth.test.d.ts +2 -0
- package/dist/middleware/apiKeyAuth.test.d.ts.map +1 -0
- package/dist/middleware/apiKeyAuth.test.js +126 -0
- package/dist/middleware/jsonRpcHandler.d.ts +11 -1
- package/dist/middleware/jsonRpcHandler.d.ts.map +1 -1
- package/dist/middleware/jsonRpcHandler.js +14 -15
- package/dist/middleware/jsonRpcHandler.test.d.ts +2 -0
- package/dist/middleware/jsonRpcHandler.test.d.ts.map +1 -0
- package/dist/middleware/jsonRpcHandler.test.js +254 -0
- package/dist/middleware/jwtAuth.d.ts.map +1 -1
- package/dist/middleware/jwtAuth.js +4 -0
- package/dist/middleware/jwtAuth.test.d.ts +2 -0
- package/dist/middleware/jwtAuth.test.d.ts.map +1 -0
- package/dist/middleware/jwtAuth.test.js +93 -0
- package/dist/middleware/rateLimit.test.js +12 -0
- package/dist/middleware/sessionHandler.js +1 -1
- package/dist/middleware/sessionHandler.test.d.ts +2 -0
- package/dist/middleware/sessionHandler.test.d.ts.map +1 -0
- package/dist/middleware/sessionHandler.test.js +121 -0
- package/dist/notification/NotificationService.test.d.ts +2 -0
- package/dist/notification/NotificationService.test.d.ts.map +1 -0
- package/dist/notification/NotificationService.test.js +110 -0
- package/dist/signing/service-account-session.d.ts +16 -0
- package/dist/signing/service-account-session.d.ts.map +1 -0
- package/dist/signing/service-account-session.js +25 -0
- package/dist/signing/service-account-session.test.d.ts +2 -0
- package/dist/signing/service-account-session.test.d.ts.map +1 -0
- package/dist/signing/service-account-session.test.js +89 -0
- package/dist/signing/signing-drivers.d.ts +7 -0
- package/dist/signing/signing-drivers.d.ts.map +1 -0
- package/dist/signing/signing-drivers.js +3 -0
- package/dist/signing/signing-worker.d.ts +83 -0
- package/dist/signing/signing-worker.d.ts.map +1 -0
- package/dist/signing/signing-worker.js +206 -0
- package/dist/signing/signing-worker.test.d.ts +2 -0
- package/dist/signing/signing-worker.test.d.ts.map +1 -0
- package/dist/signing/signing-worker.test.js +152 -0
- package/dist/user-api/controller.d.ts +6 -4
- package/dist/user-api/controller.d.ts.map +1 -1
- package/dist/user-api/controller.js +119 -95
- package/dist/user-api/controller.test.d.ts +2 -0
- package/dist/user-api/controller.test.d.ts.map +1 -0
- package/dist/user-api/controller.test.js +862 -0
- package/dist/user-api/rpc-gen/index.d.ts +12 -0
- package/dist/user-api/rpc-gen/index.d.ts.map +1 -1
- package/dist/user-api/rpc-gen/index.js +4 -0
- package/dist/user-api/rpc-gen/typings.d.ts +52 -3
- package/dist/user-api/rpc-gen/typings.d.ts.map +1 -1
- package/dist/utils.d.ts +17 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +53 -2
- package/dist/utils.test.d.ts +2 -0
- package/dist/utils.test.d.ts.map +1 -0
- package/dist/utils.test.js +24 -0
- package/dist/web/frontend/404/index.html +2 -2
- package/dist/web/frontend/activities/index.html +3 -3
- package/dist/web/frontend/approve/index.html +4 -4
- package/dist/web/frontend/assets/{404-C7V2yl2z.js → 404-C4hCL2o8.js} +2 -2
- package/dist/web/frontend/assets/{activities-NY8oZAkH.js → activities-Bq7yMMQY.js} +2 -2
- package/dist/web/frontend/assets/addIdentityProvider-DRJWLhHF.js +28 -0
- package/dist/web/frontend/assets/addNetwork-CJUaKP1q.js +38 -0
- package/dist/web/frontend/assets/addParty-2ObTLGIL.js +45 -0
- package/dist/web/frontend/assets/approve-BuA5DGC2.js +21 -0
- package/dist/web/frontend/assets/callback-C5vJWFLq.js +1 -0
- package/dist/web/frontend/assets/{identityProviders-BZ9h_VOJ.js → identityProviders-78FbpzYL.js} +2 -2
- package/dist/web/frontend/assets/{index-B-HiKugW.js → index-BTH_md6b.js} +3 -3
- package/dist/web/frontend/assets/index-CFnOucPK.js +4737 -0
- package/dist/web/frontend/assets/{login-CqwMEG9J.js → login-Dyn1o6fW.js} +2 -2
- package/dist/web/frontend/assets/{networks-BJvRi47M.js → networks-_el10AWP.js} +2 -2
- package/dist/web/frontend/assets/reviewIdentityProvider-DodUZ2mY.js +43 -0
- package/dist/web/frontend/assets/reviewNetwork-BFMtmKEL.js +43 -0
- package/dist/web/frontend/assets/settings-BBmkIfYm.js +37 -0
- package/dist/web/frontend/assets/{state-qAsNw5qf.js → state-DkxLvywv.js} +1 -1
- package/dist/web/frontend/assets/{utils-BDkHxi8V.js → utils-DvJKIYxT.js} +1 -1
- package/dist/web/frontend/callback/index.html +2 -2
- package/dist/web/frontend/identity-providers/add/index.html +3 -3
- package/dist/web/frontend/identity-providers/index.html +3 -3
- package/dist/web/frontend/identity-providers/review/index.html +3 -3
- package/dist/web/frontend/index.html +1 -1
- package/dist/web/frontend/login/index.html +3 -3
- package/dist/web/frontend/networks/add/index.html +3 -3
- package/dist/web/frontend/networks/index.html +3 -3
- package/dist/web/frontend/networks/review/index.html +3 -3
- package/dist/web/frontend/parties/add/index.html +5 -5
- package/dist/web/frontend/parties/index.html +4 -4
- package/dist/web/frontend/settings/index.html +3 -3
- package/package.json +36 -32
- package/dist/web/frontend/assets/addIdentityProvider-38ghz3RT.js +0 -28
- package/dist/web/frontend/assets/addNetwork-BaDhbrZl.js +0 -38
- package/dist/web/frontend/assets/addParty-j3JWZX5a.js +0 -41
- package/dist/web/frontend/assets/approve-43nVzAAC.js +0 -21
- package/dist/web/frontend/assets/callback-BBMiCjHR.js +0 -1
- package/dist/web/frontend/assets/index-DoNqknyE.js +0 -4042
- package/dist/web/frontend/assets/reviewIdentityProvider-ySlQnw5R.js +0 -43
- package/dist/web/frontend/assets/reviewNetwork-DrVxeHd4.js +0 -43
- package/dist/web/frontend/assets/settings-BVNkaUyJ.js +0 -37
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-auth-service.d.ts","sourceRoot":"","sources":["../../src/auth/jwt-auth-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"jwt-auth-service.d.ts","sourceRoot":"","sources":["../../src/auth/jwt-auth-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAoB,MAAM,kCAAkC,CAAA;AAChF,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAA;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAE7B;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,KAAK,EAAE,QAAQ,MAAM,KAAG,WAiI5D,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { resolveUserEmail } from '@canton-network/core-wallet-auth';
|
|
3
4
|
import { createRemoteJWKSet, decodeJwt, jwtVerify } from 'jose';
|
|
4
5
|
/**
|
|
5
6
|
* Creates an AuthService that verifies JWT tokens using a remote JWK set.
|
|
@@ -38,7 +39,6 @@ export const jwtAuthService = (store, logger) => ({
|
|
|
38
39
|
return undefined;
|
|
39
40
|
}
|
|
40
41
|
if (idp.type == 'self_signed') {
|
|
41
|
-
logger.debug(idp, 'Using self-signed IDP');
|
|
42
42
|
const sub = decoded.sub;
|
|
43
43
|
if (!sub) {
|
|
44
44
|
logger.warn('JWT does not contain a subject');
|
|
@@ -51,7 +51,7 @@ export const jwtAuthService = (store, logger) => ({
|
|
|
51
51
|
...(email ? { email } : {}),
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
logger.debug(idp, 'Using IDP');
|
|
54
|
+
logger.debug({ idp }, 'Using IDP');
|
|
55
55
|
const response = await fetch(idp.configUrl);
|
|
56
56
|
const config = await response.json();
|
|
57
57
|
const jwks = createRemoteJWKSet(new URL(config.jwks_uri));
|
|
@@ -91,12 +91,13 @@ export const jwtAuthService = (store, logger) => ({
|
|
|
91
91
|
accessToken: jwt,
|
|
92
92
|
email: getEmail(decoded.email),
|
|
93
93
|
}, 'JWT verified');
|
|
94
|
-
const
|
|
95
|
-
return {
|
|
94
|
+
const authContext = {
|
|
96
95
|
userId: payload.sub,
|
|
97
96
|
accessToken: jwt,
|
|
98
|
-
...(email ? { email } : {}),
|
|
99
97
|
};
|
|
98
|
+
const email = getEmail(decoded.email) ??
|
|
99
|
+
(await resolveUserEmail(authContext, idp, logger));
|
|
100
|
+
return email ? { ...authContext, email } : authContext;
|
|
100
101
|
}
|
|
101
102
|
catch (error) {
|
|
102
103
|
if (error instanceof Error) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-auth-service.test.d.ts","sourceRoot":"","sources":["../../src/auth/jwt-auth-service.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
4
|
+
import { pino } from 'pino';
|
|
5
|
+
import { sink } from 'pino-test';
|
|
6
|
+
import { SignJWT } from 'jose';
|
|
7
|
+
import { StoreInternal } from '@canton-network/core-wallet-store-inmemory';
|
|
8
|
+
import { jwtAuthService } from './jwt-auth-service.js';
|
|
9
|
+
const mockJwtVerify = vi.hoisted(() => vi.fn());
|
|
10
|
+
const mockCreateRemoteJWKSet = vi.hoisted(() => vi.fn(() => 'jwks'));
|
|
11
|
+
const mockFetch = vi.hoisted(() => vi.fn());
|
|
12
|
+
vi.mock('jose', async (importOriginal) => {
|
|
13
|
+
const actual = await importOriginal();
|
|
14
|
+
return {
|
|
15
|
+
...actual,
|
|
16
|
+
jwtVerify: mockJwtVerify,
|
|
17
|
+
createRemoteJWKSet: mockCreateRemoteJWKSet,
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
const authContext = {
|
|
21
|
+
userId: 'test-user-id',
|
|
22
|
+
accessToken: 'test-access-token',
|
|
23
|
+
};
|
|
24
|
+
const SELF_SIGNED_ISSUER = 'unsafe-auth';
|
|
25
|
+
const OAUTH_ISSUER = 'https://oauth.example.com';
|
|
26
|
+
async function bearerToken(claims) {
|
|
27
|
+
const jwt = await new SignJWT(claims)
|
|
28
|
+
.setProtectedHeader({ alg: 'HS256' })
|
|
29
|
+
.sign(new TextEncoder().encode('test-secret'));
|
|
30
|
+
return `Bearer ${jwt}`;
|
|
31
|
+
}
|
|
32
|
+
const createNetwork = (id, identityProviderId, audience = 'test-audience') => ({
|
|
33
|
+
id,
|
|
34
|
+
name: `Network ${id}`,
|
|
35
|
+
synchronizerId: `${id}-sync`,
|
|
36
|
+
identityProviderId,
|
|
37
|
+
description: `Test Network ${id}`,
|
|
38
|
+
ledgerApi: { baseUrl: `http://${id}` },
|
|
39
|
+
auth: {
|
|
40
|
+
method: 'authorization_code',
|
|
41
|
+
clientId: 'cid',
|
|
42
|
+
scope: 'openid',
|
|
43
|
+
audience,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
describe('jwtAuthService', () => {
|
|
47
|
+
let mockLogger;
|
|
48
|
+
let store;
|
|
49
|
+
beforeEach(async () => {
|
|
50
|
+
mockLogger = pino(sink());
|
|
51
|
+
store = new StoreInternal({ idps: [], networks: [] }, mockLogger, authContext);
|
|
52
|
+
vi.stubGlobal('fetch', mockFetch);
|
|
53
|
+
mockFetch.mockReset();
|
|
54
|
+
mockJwtVerify.mockReset();
|
|
55
|
+
mockCreateRemoteJWKSet.mockClear();
|
|
56
|
+
});
|
|
57
|
+
afterEach(() => {
|
|
58
|
+
vi.unstubAllGlobals();
|
|
59
|
+
vi.restoreAllMocks();
|
|
60
|
+
});
|
|
61
|
+
it('returns undefined when access token is missing', async () => {
|
|
62
|
+
const service = jwtAuthService(store, mockLogger);
|
|
63
|
+
await expect(service.verifyToken(undefined)).resolves.toBeUndefined();
|
|
64
|
+
});
|
|
65
|
+
it('returns undefined when authorization header is not Bearer', async () => {
|
|
66
|
+
const service = jwtAuthService(store, mockLogger);
|
|
67
|
+
await expect(service.verifyToken('Basic abc')).resolves.toBeUndefined();
|
|
68
|
+
});
|
|
69
|
+
it('returns undefined when JWT has no issuer', async () => {
|
|
70
|
+
const service = jwtAuthService(store, mockLogger);
|
|
71
|
+
const token = await bearerToken({ sub: 'user-1', scope: 'openid' });
|
|
72
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
it('returns undefined when no identity provider matches issuer', async () => {
|
|
75
|
+
await store.addIdp({
|
|
76
|
+
id: 'idp-self',
|
|
77
|
+
type: 'self_signed',
|
|
78
|
+
issuer: SELF_SIGNED_ISSUER,
|
|
79
|
+
});
|
|
80
|
+
const service = jwtAuthService(store, mockLogger);
|
|
81
|
+
const token = await bearerToken({
|
|
82
|
+
iss: 'unknown-issuer',
|
|
83
|
+
sub: 'user-1',
|
|
84
|
+
scope: 'openid',
|
|
85
|
+
});
|
|
86
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
87
|
+
});
|
|
88
|
+
it('returns undefined when JWT has no scope or scp claim', async () => {
|
|
89
|
+
await store.addIdp({
|
|
90
|
+
id: 'idp-self',
|
|
91
|
+
type: 'self_signed',
|
|
92
|
+
issuer: SELF_SIGNED_ISSUER,
|
|
93
|
+
});
|
|
94
|
+
const service = jwtAuthService(store, mockLogger);
|
|
95
|
+
const token = await bearerToken({
|
|
96
|
+
iss: SELF_SIGNED_ISSUER,
|
|
97
|
+
sub: 'user-1',
|
|
98
|
+
});
|
|
99
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
100
|
+
});
|
|
101
|
+
describe('self_signed identity provider', () => {
|
|
102
|
+
beforeEach(async () => {
|
|
103
|
+
await store.addIdp({
|
|
104
|
+
id: 'idp-self',
|
|
105
|
+
type: 'self_signed',
|
|
106
|
+
issuer: SELF_SIGNED_ISSUER,
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
it('returns auth context for a valid self-signed token', async () => {
|
|
110
|
+
const service = jwtAuthService(store, mockLogger);
|
|
111
|
+
const token = await bearerToken({
|
|
112
|
+
iss: SELF_SIGNED_ISSUER,
|
|
113
|
+
sub: 'user-1',
|
|
114
|
+
scope: 'openid',
|
|
115
|
+
});
|
|
116
|
+
const result = await service.verifyToken(token);
|
|
117
|
+
expect(result).toEqual({
|
|
118
|
+
userId: 'user-1',
|
|
119
|
+
accessToken: token.split(' ')[1],
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
it('accepts scp claim instead of scope', async () => {
|
|
123
|
+
const service = jwtAuthService(store, mockLogger);
|
|
124
|
+
const token = await bearerToken({
|
|
125
|
+
iss: SELF_SIGNED_ISSUER,
|
|
126
|
+
sub: 'user-1',
|
|
127
|
+
scp: 'openid',
|
|
128
|
+
});
|
|
129
|
+
const result = await service.verifyToken(token);
|
|
130
|
+
expect(result?.userId).toBe('user-1');
|
|
131
|
+
});
|
|
132
|
+
it('includes email when present in token', async () => {
|
|
133
|
+
const service = jwtAuthService(store, mockLogger);
|
|
134
|
+
const token = await bearerToken({
|
|
135
|
+
iss: SELF_SIGNED_ISSUER,
|
|
136
|
+
sub: 'user-1',
|
|
137
|
+
scope: 'openid',
|
|
138
|
+
email: 'user@example.com',
|
|
139
|
+
});
|
|
140
|
+
const result = await service.verifyToken(token);
|
|
141
|
+
expect(result).toEqual({
|
|
142
|
+
userId: 'user-1',
|
|
143
|
+
accessToken: token.split(' ')[1],
|
|
144
|
+
email: 'user@example.com',
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
it('returns undefined when JWT has no subject', async () => {
|
|
148
|
+
const service = jwtAuthService(store, mockLogger);
|
|
149
|
+
const token = await bearerToken({
|
|
150
|
+
iss: SELF_SIGNED_ISSUER,
|
|
151
|
+
scope: 'openid',
|
|
152
|
+
});
|
|
153
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
describe('oauth identity provider', () => {
|
|
157
|
+
const configUrl = 'https://oauth.example.com/.well-known/openid-configuration';
|
|
158
|
+
beforeEach(async () => {
|
|
159
|
+
await store.addIdp({
|
|
160
|
+
id: 'idp-oauth',
|
|
161
|
+
type: 'oauth',
|
|
162
|
+
issuer: OAUTH_ISSUER,
|
|
163
|
+
configUrl,
|
|
164
|
+
});
|
|
165
|
+
mockFetch.mockResolvedValue({
|
|
166
|
+
json: async () => ({
|
|
167
|
+
jwks_uri: 'https://oauth.example.com/jwks',
|
|
168
|
+
}),
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
it('returns auth context when JWT verifies and audience matches', async () => {
|
|
172
|
+
await store.addNetwork(createNetwork('network-1', 'idp-oauth', 'ledger-audience'));
|
|
173
|
+
mockJwtVerify.mockResolvedValue({
|
|
174
|
+
payload: { sub: 'oauth-user', aud: 'ledger-audience' },
|
|
175
|
+
});
|
|
176
|
+
const service = jwtAuthService(store, mockLogger);
|
|
177
|
+
const token = await bearerToken({
|
|
178
|
+
iss: OAUTH_ISSUER,
|
|
179
|
+
sub: 'oauth-user',
|
|
180
|
+
scope: 'openid',
|
|
181
|
+
email: 'oauth@example.com',
|
|
182
|
+
});
|
|
183
|
+
const rawJwt = token.split(' ')[1];
|
|
184
|
+
const result = await service.verifyToken(token);
|
|
185
|
+
expect(mockFetch).toHaveBeenCalledWith(configUrl);
|
|
186
|
+
expect(mockCreateRemoteJWKSet).toHaveBeenCalledWith(new URL('https://oauth.example.com/jwks'));
|
|
187
|
+
expect(mockJwtVerify).toHaveBeenCalledWith(rawJwt, 'jwks', {
|
|
188
|
+
algorithms: ['RS256'],
|
|
189
|
+
});
|
|
190
|
+
expect(result).toEqual({
|
|
191
|
+
userId: 'oauth-user',
|
|
192
|
+
accessToken: rawJwt,
|
|
193
|
+
email: 'oauth@example.com',
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
it('returns undefined when no networks are configured for the IDP', async () => {
|
|
197
|
+
mockJwtVerify.mockResolvedValue({
|
|
198
|
+
payload: { sub: 'oauth-user', aud: 'ledger-audience' },
|
|
199
|
+
});
|
|
200
|
+
const service = jwtAuthService(store, mockLogger);
|
|
201
|
+
const token = await bearerToken({
|
|
202
|
+
iss: OAUTH_ISSUER,
|
|
203
|
+
sub: 'oauth-user',
|
|
204
|
+
scope: 'openid',
|
|
205
|
+
});
|
|
206
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
207
|
+
});
|
|
208
|
+
it('returns undefined when audience does not match configured networks', async () => {
|
|
209
|
+
await store.addNetwork(createNetwork('network-1', 'idp-oauth', 'expected-audience'));
|
|
210
|
+
mockJwtVerify.mockResolvedValue({
|
|
211
|
+
payload: { sub: 'oauth-user', aud: 'other-audience' },
|
|
212
|
+
});
|
|
213
|
+
const service = jwtAuthService(store, mockLogger);
|
|
214
|
+
const token = await bearerToken({
|
|
215
|
+
iss: OAUTH_ISSUER,
|
|
216
|
+
sub: 'oauth-user',
|
|
217
|
+
scope: 'openid',
|
|
218
|
+
});
|
|
219
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
220
|
+
});
|
|
221
|
+
it('returns undefined when verified JWT has no audience', async () => {
|
|
222
|
+
await store.addNetwork(createNetwork('network-1', 'idp-oauth', 'expected-audience'));
|
|
223
|
+
mockJwtVerify.mockResolvedValue({
|
|
224
|
+
payload: { sub: 'oauth-user' },
|
|
225
|
+
});
|
|
226
|
+
const service = jwtAuthService(store, mockLogger);
|
|
227
|
+
const token = await bearerToken({
|
|
228
|
+
iss: OAUTH_ISSUER,
|
|
229
|
+
sub: 'oauth-user',
|
|
230
|
+
scope: 'openid',
|
|
231
|
+
});
|
|
232
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
233
|
+
});
|
|
234
|
+
it('returns undefined when verified JWT has no subject', async () => {
|
|
235
|
+
await store.addNetwork(createNetwork('network-1', 'idp-oauth', 'expected-audience'));
|
|
236
|
+
mockJwtVerify.mockResolvedValue({
|
|
237
|
+
payload: { aud: 'expected-audience' },
|
|
238
|
+
});
|
|
239
|
+
const service = jwtAuthService(store, mockLogger);
|
|
240
|
+
const token = await bearerToken({
|
|
241
|
+
iss: OAUTH_ISSUER,
|
|
242
|
+
sub: 'oauth-user',
|
|
243
|
+
scope: 'openid',
|
|
244
|
+
});
|
|
245
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
246
|
+
});
|
|
247
|
+
it('returns undefined when JWT verification fails', async () => {
|
|
248
|
+
await store.addNetwork(createNetwork('network-1', 'idp-oauth', 'expected-audience'));
|
|
249
|
+
mockJwtVerify.mockRejectedValue(new Error('invalid signature'));
|
|
250
|
+
const service = jwtAuthService(store, mockLogger);
|
|
251
|
+
const token = await bearerToken({
|
|
252
|
+
iss: OAUTH_ISSUER,
|
|
253
|
+
sub: 'oauth-user',
|
|
254
|
+
scope: 'openid',
|
|
255
|
+
});
|
|
256
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-unsafe-auth-service.test.d.ts","sourceRoot":"","sources":["../../src/auth/jwt-unsafe-auth-service.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
4
|
+
import { pino } from 'pino';
|
|
5
|
+
import { sink } from 'pino-test';
|
|
6
|
+
import { SignJWT } from 'jose';
|
|
7
|
+
import { StoreInternal } from '@canton-network/core-wallet-store-inmemory';
|
|
8
|
+
import { jwtAuthService as jwtUnsafeAuthService } from './jwt-unsafe-auth-service.js';
|
|
9
|
+
const authContext = {
|
|
10
|
+
userId: 'test-user-id',
|
|
11
|
+
accessToken: 'test-access-token',
|
|
12
|
+
};
|
|
13
|
+
const SELF_SIGNED_ISSUER = 'unsafe-auth';
|
|
14
|
+
async function bearerToken(claims) {
|
|
15
|
+
const jwt = await new SignJWT(claims)
|
|
16
|
+
.setProtectedHeader({ alg: 'HS256' })
|
|
17
|
+
.sign(new TextEncoder().encode('test-secret'));
|
|
18
|
+
return `Bearer ${jwt}`;
|
|
19
|
+
}
|
|
20
|
+
describe('jwtAuthService (unsafe)', () => {
|
|
21
|
+
let mockLogger;
|
|
22
|
+
let store;
|
|
23
|
+
beforeEach(async () => {
|
|
24
|
+
mockLogger = pino(sink());
|
|
25
|
+
store = new StoreInternal({ idps: [], networks: [] }, mockLogger, authContext);
|
|
26
|
+
await store.addIdp({
|
|
27
|
+
id: 'idp-self',
|
|
28
|
+
type: 'self_signed',
|
|
29
|
+
issuer: SELF_SIGNED_ISSUER,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
it('returns undefined when access token is missing', async () => {
|
|
33
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
34
|
+
await expect(service.verifyToken(undefined)).resolves.toBeUndefined();
|
|
35
|
+
});
|
|
36
|
+
it('returns undefined when authorization header is not Bearer', async () => {
|
|
37
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
38
|
+
await expect(service.verifyToken('NotBearer abc')).resolves.toBeUndefined();
|
|
39
|
+
});
|
|
40
|
+
it('returns undefined when JWT has no issuer', async () => {
|
|
41
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
42
|
+
const token = await bearerToken({
|
|
43
|
+
sub: 'user-1',
|
|
44
|
+
scope: 'openid',
|
|
45
|
+
});
|
|
46
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
47
|
+
});
|
|
48
|
+
it('returns undefined when JWT has no subject', async () => {
|
|
49
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
50
|
+
const token = await bearerToken({
|
|
51
|
+
iss: SELF_SIGNED_ISSUER,
|
|
52
|
+
scope: 'openid',
|
|
53
|
+
});
|
|
54
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
55
|
+
});
|
|
56
|
+
it('returns undefined when JWT has no scope claim', async () => {
|
|
57
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
58
|
+
const token = await bearerToken({
|
|
59
|
+
iss: SELF_SIGNED_ISSUER,
|
|
60
|
+
sub: 'user-1',
|
|
61
|
+
});
|
|
62
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
63
|
+
});
|
|
64
|
+
it('returns undefined when no identity provider matches issuer', async () => {
|
|
65
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
66
|
+
const token = await bearerToken({
|
|
67
|
+
iss: 'unknown-issuer',
|
|
68
|
+
sub: 'user-1',
|
|
69
|
+
scope: 'openid',
|
|
70
|
+
});
|
|
71
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
72
|
+
});
|
|
73
|
+
it('returns undefined for oauth identity providers', async () => {
|
|
74
|
+
await store.addIdp({
|
|
75
|
+
id: 'idp-oauth',
|
|
76
|
+
type: 'oauth',
|
|
77
|
+
issuer: 'https://oauth.example.com',
|
|
78
|
+
configUrl: 'https://oauth.example.com/.well-known/openid-configuration',
|
|
79
|
+
});
|
|
80
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
81
|
+
const token = await bearerToken({
|
|
82
|
+
iss: 'https://oauth.example.com',
|
|
83
|
+
sub: 'user-1',
|
|
84
|
+
scope: 'openid',
|
|
85
|
+
});
|
|
86
|
+
await expect(service.verifyToken(token)).resolves.toBeUndefined();
|
|
87
|
+
});
|
|
88
|
+
it('returns auth context for a valid self-signed token', async () => {
|
|
89
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
90
|
+
const token = await bearerToken({
|
|
91
|
+
iss: SELF_SIGNED_ISSUER,
|
|
92
|
+
sub: 'user-1',
|
|
93
|
+
scope: 'openid',
|
|
94
|
+
});
|
|
95
|
+
const result = await service.verifyToken(token);
|
|
96
|
+
expect(result).toEqual({
|
|
97
|
+
userId: 'user-1',
|
|
98
|
+
accessToken: token.split(' ')[1],
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
it('includes email when present in token', async () => {
|
|
102
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
103
|
+
const token = await bearerToken({
|
|
104
|
+
iss: SELF_SIGNED_ISSUER,
|
|
105
|
+
sub: 'user-1',
|
|
106
|
+
scope: 'openid',
|
|
107
|
+
email: 'user@example.com',
|
|
108
|
+
});
|
|
109
|
+
const result = await service.verifyToken(token);
|
|
110
|
+
expect(result).toEqual({
|
|
111
|
+
userId: 'user-1',
|
|
112
|
+
accessToken: token.split(' ')[1],
|
|
113
|
+
email: 'user@example.com',
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
it('returns undefined for malformed JWT', async () => {
|
|
117
|
+
const service = jwtUnsafeAuthService(store, mockLogger);
|
|
118
|
+
await expect(service.verifyToken('Bearer not-a-jwt')).resolves.toBeUndefined();
|
|
119
|
+
});
|
|
120
|
+
});
|
package/dist/config/Config.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export declare const serverConfigSchema: z.ZodObject<{
|
|
|
15
15
|
requestRateLimit: z.ZodDefault<z.ZodNumber>;
|
|
16
16
|
trustProxy: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodString]>>;
|
|
17
17
|
admin: z.ZodOptional<z.ZodString>;
|
|
18
|
+
signingWorker: z.ZodPreprocess<z.ZodObject<{
|
|
19
|
+
pollInterval: z.ZodDefault<z.ZodNumber>;
|
|
20
|
+
}, z.core.$strip>>;
|
|
18
21
|
}, z.core.$strip>;
|
|
19
22
|
export declare const rawConfigSchema: z.ZodObject<{
|
|
20
23
|
kernel: z.ZodObject<{
|
|
@@ -22,7 +25,7 @@ export declare const rawConfigSchema: z.ZodObject<{
|
|
|
22
25
|
publicUrl: z.ZodOptional<z.ZodString>;
|
|
23
26
|
clientType: z.ZodUnion<readonly [z.ZodLiteral<"browser">, z.ZodLiteral<"desktop">, z.ZodLiteral<"mobile">, z.ZodLiteral<"remote">]>;
|
|
24
27
|
}, z.core.$strip>;
|
|
25
|
-
server: z.
|
|
28
|
+
server: z.ZodPreprocess<z.ZodObject<{
|
|
26
29
|
port: z.ZodDefault<z.ZodNumber>;
|
|
27
30
|
dappPath: z.ZodDefault<z.ZodString>;
|
|
28
31
|
userPath: z.ZodDefault<z.ZodString>;
|
|
@@ -33,8 +36,11 @@ export declare const rawConfigSchema: z.ZodObject<{
|
|
|
33
36
|
requestRateLimit: z.ZodDefault<z.ZodNumber>;
|
|
34
37
|
trustProxy: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodString]>>;
|
|
35
38
|
admin: z.ZodOptional<z.ZodString>;
|
|
39
|
+
signingWorker: z.ZodPreprocess<z.ZodObject<{
|
|
40
|
+
pollInterval: z.ZodDefault<z.ZodNumber>;
|
|
41
|
+
}, z.core.$strip>>;
|
|
36
42
|
}, z.core.$strip>>;
|
|
37
|
-
logging: z.ZodOptional<z.
|
|
43
|
+
logging: z.ZodOptional<z.ZodPreprocess<z.ZodObject<{
|
|
38
44
|
level: z.ZodOptional<z.ZodEnum<{
|
|
39
45
|
error: "error";
|
|
40
46
|
trace: "trace";
|
|
@@ -172,6 +178,43 @@ export declare const rawConfigSchema: z.ZodObject<{
|
|
|
172
178
|
clientId: z.ZodString;
|
|
173
179
|
clientSecretEnv: z.ZodString;
|
|
174
180
|
}, z.core.$strip>], "method">]>>;
|
|
181
|
+
serviceAccountAuth: z.ZodOptional<z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
182
|
+
method: z.ZodLiteral<"authorization_code">;
|
|
183
|
+
audience: z.ZodString;
|
|
184
|
+
scope: z.ZodString;
|
|
185
|
+
clientId: z.ZodString;
|
|
186
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
187
|
+
method: z.ZodLiteral<"client_credentials">;
|
|
188
|
+
audience: z.ZodString;
|
|
189
|
+
scope: z.ZodString;
|
|
190
|
+
clientId: z.ZodString;
|
|
191
|
+
clientSecret: z.ZodString;
|
|
192
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
193
|
+
method: z.ZodLiteral<"self_signed">;
|
|
194
|
+
issuer: z.ZodString;
|
|
195
|
+
audience: z.ZodString;
|
|
196
|
+
scope: z.ZodString;
|
|
197
|
+
clientId: z.ZodString;
|
|
198
|
+
clientSecret: z.ZodString;
|
|
199
|
+
}, z.core.$strip>], "method">, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
200
|
+
method: z.ZodLiteral<"authorization_code">;
|
|
201
|
+
audience: z.ZodString;
|
|
202
|
+
scope: z.ZodString;
|
|
203
|
+
clientId: z.ZodString;
|
|
204
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
205
|
+
method: z.ZodLiteral<"client_credentials">;
|
|
206
|
+
audience: z.ZodString;
|
|
207
|
+
scope: z.ZodString;
|
|
208
|
+
clientId: z.ZodString;
|
|
209
|
+
clientSecretEnv: z.ZodString;
|
|
210
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
211
|
+
method: z.ZodLiteral<"self_signed">;
|
|
212
|
+
issuer: z.ZodString;
|
|
213
|
+
audience: z.ZodString;
|
|
214
|
+
scope: z.ZodString;
|
|
215
|
+
clientId: z.ZodString;
|
|
216
|
+
clientSecretEnv: z.ZodString;
|
|
217
|
+
}, z.core.$strip>], "method">]>>;
|
|
175
218
|
}, z.core.$strip>>;
|
|
176
219
|
}, z.core.$strip>;
|
|
177
220
|
}, z.core.$strip>;
|
|
@@ -181,7 +224,7 @@ export declare const configSchema: z.ZodObject<{
|
|
|
181
224
|
publicUrl: z.ZodOptional<z.ZodString>;
|
|
182
225
|
clientType: z.ZodUnion<readonly [z.ZodLiteral<"browser">, z.ZodLiteral<"desktop">, z.ZodLiteral<"mobile">, z.ZodLiteral<"remote">]>;
|
|
183
226
|
}, z.core.$strip>;
|
|
184
|
-
server: z.
|
|
227
|
+
server: z.ZodPreprocess<z.ZodObject<{
|
|
185
228
|
port: z.ZodDefault<z.ZodNumber>;
|
|
186
229
|
dappPath: z.ZodDefault<z.ZodString>;
|
|
187
230
|
userPath: z.ZodDefault<z.ZodString>;
|
|
@@ -192,8 +235,11 @@ export declare const configSchema: z.ZodObject<{
|
|
|
192
235
|
requestRateLimit: z.ZodDefault<z.ZodNumber>;
|
|
193
236
|
trustProxy: z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodString]>>;
|
|
194
237
|
admin: z.ZodOptional<z.ZodString>;
|
|
238
|
+
signingWorker: z.ZodPreprocess<z.ZodObject<{
|
|
239
|
+
pollInterval: z.ZodDefault<z.ZodNumber>;
|
|
240
|
+
}, z.core.$strip>>;
|
|
195
241
|
}, z.core.$strip>>;
|
|
196
|
-
logging: z.ZodOptional<z.
|
|
242
|
+
logging: z.ZodOptional<z.ZodPreprocess<z.ZodObject<{
|
|
197
243
|
level: z.ZodOptional<z.ZodEnum<{
|
|
198
244
|
error: "error";
|
|
199
245
|
trace: "trace";
|
|
@@ -295,6 +341,25 @@ export declare const configSchema: z.ZodObject<{
|
|
|
295
341
|
clientId: z.ZodString;
|
|
296
342
|
clientSecret: z.ZodString;
|
|
297
343
|
}, z.core.$strip>], "method">>;
|
|
344
|
+
serviceAccountAuth: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
345
|
+
method: z.ZodLiteral<"authorization_code">;
|
|
346
|
+
audience: z.ZodString;
|
|
347
|
+
scope: z.ZodString;
|
|
348
|
+
clientId: z.ZodString;
|
|
349
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
350
|
+
method: z.ZodLiteral<"client_credentials">;
|
|
351
|
+
audience: z.ZodString;
|
|
352
|
+
scope: z.ZodString;
|
|
353
|
+
clientId: z.ZodString;
|
|
354
|
+
clientSecret: z.ZodString;
|
|
355
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
356
|
+
method: z.ZodLiteral<"self_signed">;
|
|
357
|
+
issuer: z.ZodString;
|
|
358
|
+
audience: z.ZodString;
|
|
359
|
+
scope: z.ZodString;
|
|
360
|
+
clientId: z.ZodString;
|
|
361
|
+
clientSecret: z.ZodString;
|
|
362
|
+
}, z.core.$strip>], "method">>;
|
|
298
363
|
}, z.core.$strip>>;
|
|
299
364
|
}, z.core.$strip>;
|
|
300
365
|
}, z.core.$strip>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/config/Config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AASvB,eAAO,MAAM,gBAAgB;;;;iBAY3B,CAAA;AAEF,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../src/config/Config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AASvB,eAAO,MAAM,gBAAgB;;;;iBAY3B,CAAA;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;iBA0D7B,CAAA;AAkCF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAO1B,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAOvB,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAC7D,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AACvD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA"}
|
package/dist/config/Config.js
CHANGED
|
@@ -57,6 +57,11 @@ export const serverConfigSchema = z.object({
|
|
|
57
57
|
admin: z.string().optional().meta({
|
|
58
58
|
description: 'The JWT claim (e.g. "sub") identifying the admin user. If set, requests with a matching claim will be granted admin privileges.',
|
|
59
59
|
}),
|
|
60
|
+
signingWorker: z.preprocess((val) => val ?? {}, z.object({
|
|
61
|
+
pollInterval: z.number().int().positive().default(5000).meta({
|
|
62
|
+
description: 'Interval in milliseconds for the signing worker to poll external signing providers on pending transactions. Defaults to 5000.',
|
|
63
|
+
}),
|
|
64
|
+
})),
|
|
60
65
|
});
|
|
61
66
|
const loggingConfigSchema = z
|
|
62
67
|
.object({
|
|
@@ -78,6 +83,7 @@ const bootstrapFromEnv = bootstrapConfigSchema.extend({
|
|
|
78
83
|
networks: z.array(networkSchema.extend({
|
|
79
84
|
auth: authFromEnvOrConfig,
|
|
80
85
|
adminAuth: authFromEnvOrConfig.optional(),
|
|
86
|
+
serviceAccountAuth: authFromEnvOrConfig.optional(),
|
|
81
87
|
})),
|
|
82
88
|
});
|
|
83
89
|
// Includes secrets for networks as env vars, rather than defined explicitly
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigUtils.d.ts","sourceRoot":"","sources":["../../src/config/ConfigUtils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAA8B,MAAM,aAAa,CAAA;AAGhE,qBAAa,WAAW;IACpB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAsDlD;
|
|
1
|
+
{"version":3,"file":"ConfigUtils.d.ts","sourceRoot":"","sources":["../../src/config/ConfigUtils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAA8B,MAAM,aAAa,CAAA;AAGhE,qBAAa,WAAW;IACpB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAsDlD;AAkGD,UAAU,IAAI;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACrB;AAOD,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,IAa1D,CAAA"}
|
|
@@ -3,7 +3,11 @@ import { Store } from '@canton-network/core-wallet-store';
|
|
|
3
3
|
import { NotificationService } from '../notification/NotificationService.js';
|
|
4
4
|
import { KernelInfo as KernelInfoConfig } from '../config/Config.js';
|
|
5
5
|
import { Logger } from 'pino';
|
|
6
|
-
|
|
6
|
+
import { SigningDrivers } from '../signing/signing-drivers.js';
|
|
7
|
+
export interface DappControllerDeps {
|
|
8
|
+
signingDrivers: SigningDrivers;
|
|
9
|
+
}
|
|
10
|
+
export declare const dappController: (kernelInfo: KernelInfoConfig, dappUrl: string, userUrl: string, store: Store, notificationService: NotificationService, _logger: Logger, origin: string | null, deps: DappControllerDeps, context?: AuthContext) => {
|
|
7
11
|
status: import("./rpc-gen/typings.js").Status;
|
|
8
12
|
connect: import("./rpc-gen/typings.js").Connect;
|
|
9
13
|
disconnect: import("./rpc-gen/typings.js").Disconnect;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/dapp-api/controller.ts"],"names":[],"mappings":"AAGA,OAAO,EAEH,WAAW,EAEd,MAAM,kCAAkC,CAAA;AAczC,OAAO,EAAE,KAAK,EAAe,MAAM,mCAAmC,CAAA;AAQtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AAC5E,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/dapp-api/controller.ts"],"names":[],"mappings":"AAGA,OAAO,EAEH,WAAW,EAEd,MAAM,kCAAkC,CAAA;AAczC,OAAO,EAAE,KAAK,EAAe,MAAM,mCAAmC,CAAA;AAQtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AAC5E,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAK7B,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAG9D,MAAM,WAAW,kBAAkB;IAC/B,cAAc,EAAE,cAAc,CAAA;CACjC;AAED,eAAO,MAAM,cAAc,GACvB,YAAY,gBAAgB,EAC5B,SAAS,MAAM,EACf,SAAS,MAAM,EACf,OAAO,KAAK,EACZ,qBAAqB,mBAAmB,EACxC,SAAS,MAAM,EACf,QAAQ,MAAM,GAAG,IAAI,EACrB,MAAM,kBAAkB,EACxB,UAAU,WAAW;;;;;;;;;;;;;;;;CA2cxB,CAAA"}
|