@dainprotocol/service-sdk 2.0.7 → 2.0.9

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.
Files changed (80) hide show
  1. package/dist/client/client-auth.js +6 -4
  2. package/dist/client/client-auth.js.map +1 -1
  3. package/dist/client/types.d.ts +75 -429
  4. package/dist/client/types.js +1 -0
  5. package/dist/client/types.js.map +1 -1
  6. package/dist/interfaces/index.d.ts +21 -73
  7. package/dist/interfaces/index.js +1 -1
  8. package/dist/interfaces/index.js.map +1 -1
  9. package/dist/lib/schemaStructure.d.ts +3 -3
  10. package/dist/lib/schemaStructure.js +6 -5
  11. package/dist/lib/schemaStructure.js.map +1 -1
  12. package/dist/service/core.d.ts +2 -6
  13. package/dist/service/types.d.ts +1 -0
  14. package/package.json +2 -4
  15. package/dist/__tests__/api-sdk.test.d.ts +0 -1
  16. package/dist/__tests__/api-sdk.test.js +0 -102
  17. package/dist/__tests__/api-sdk.test.js.map +0 -1
  18. package/dist/__tests__/auth.test.d.ts +0 -1
  19. package/dist/__tests__/auth.test.js +0 -110
  20. package/dist/__tests__/auth.test.js.map +0 -1
  21. package/dist/__tests__/citations-plugin.test.d.ts +0 -1
  22. package/dist/__tests__/citations-plugin.test.js +0 -491
  23. package/dist/__tests__/citations-plugin.test.js.map +0 -1
  24. package/dist/__tests__/context-behavior.test.d.ts +0 -1
  25. package/dist/__tests__/context-behavior.test.js +0 -290
  26. package/dist/__tests__/context-behavior.test.js.map +0 -1
  27. package/dist/__tests__/convertToVercelTool.test.d.ts +0 -1
  28. package/dist/__tests__/convertToVercelTool.test.js +0 -527
  29. package/dist/__tests__/convertToVercelTool.test.js.map +0 -1
  30. package/dist/__tests__/core.test.d.ts +0 -1
  31. package/dist/__tests__/core.test.js +0 -154
  32. package/dist/__tests__/core.test.js.map +0 -1
  33. package/dist/__tests__/crypto-plugin.test.d.ts +0 -1
  34. package/dist/__tests__/crypto-plugin.test.js +0 -694
  35. package/dist/__tests__/crypto-plugin.test.js.map +0 -1
  36. package/dist/__tests__/humanActions.test.d.ts +0 -1
  37. package/dist/__tests__/humanActions.test.js +0 -221
  38. package/dist/__tests__/humanActions.test.js.map +0 -1
  39. package/dist/__tests__/integration.test.d.ts +0 -1
  40. package/dist/__tests__/integration.test.js +0 -1573
  41. package/dist/__tests__/integration.test.js.map +0 -1
  42. package/dist/__tests__/mealMeSchemas.test.d.ts +0 -576
  43. package/dist/__tests__/mealMeSchemas.test.js +0 -627
  44. package/dist/__tests__/mealMeSchemas.test.js.map +0 -1
  45. package/dist/__tests__/oauth.test.d.ts +0 -1
  46. package/dist/__tests__/oauth.test.js +0 -378
  47. package/dist/__tests__/oauth.test.js.map +0 -1
  48. package/dist/__tests__/oauth2-client-integration.test.d.ts +0 -1
  49. package/dist/__tests__/oauth2-client-integration.test.js +0 -182
  50. package/dist/__tests__/oauth2-client-integration.test.js.map +0 -1
  51. package/dist/__tests__/oauth2-context.test.d.ts +0 -1
  52. package/dist/__tests__/oauth2-context.test.js +0 -201
  53. package/dist/__tests__/oauth2-context.test.js.map +0 -1
  54. package/dist/__tests__/oauth2-datasource.test.d.ts +0 -1
  55. package/dist/__tests__/oauth2-datasource.test.js +0 -251
  56. package/dist/__tests__/oauth2-datasource.test.js.map +0 -1
  57. package/dist/__tests__/plugin.test.d.ts +0 -1
  58. package/dist/__tests__/plugin.test.js +0 -900
  59. package/dist/__tests__/plugin.test.js.map +0 -1
  60. package/dist/__tests__/processes.test.d.ts +0 -1
  61. package/dist/__tests__/processes.test.js +0 -239
  62. package/dist/__tests__/processes.test.js.map +0 -1
  63. package/dist/__tests__/streaming.test.d.ts +0 -1
  64. package/dist/__tests__/streaming.test.js +0 -592
  65. package/dist/__tests__/streaming.test.js.map +0 -1
  66. package/dist/__tests__/testEnums.d.ts +0 -1
  67. package/dist/__tests__/testEnums.js +0 -73
  68. package/dist/__tests__/testEnums.js.map +0 -1
  69. package/dist/__tests__/testOptionals.test.d.ts +0 -1
  70. package/dist/__tests__/testOptionals.test.js +0 -83
  71. package/dist/__tests__/testOptionals.test.js.map +0 -1
  72. package/dist/__tests__/types.test.d.ts +0 -1
  73. package/dist/__tests__/types.test.js +0 -98
  74. package/dist/__tests__/types.test.js.map +0 -1
  75. package/dist/client/service-auth.d.ts +0 -61
  76. package/dist/client/service-auth.js +0 -93
  77. package/dist/client/service-auth.js.map +0 -1
  78. package/dist/client/user-auth.d.ts +0 -74
  79. package/dist/client/user-auth.js +0 -137
  80. package/dist/client/user-auth.js.map +0 -1
@@ -1,378 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const api_sdk_1 = require("../client/api-sdk");
5
- const client_auth_1 = require("../client/client-auth");
6
- const ed25519_1 = require("@noble/curves/ed25519");
7
- const bs58_1 = tslib_1.__importDefault(require("bs58"));
8
- const nodeService_1 = require("../service/nodeService");
9
- const zod_1 = require("zod");
10
- const oauth2_token_manager_1 = require("@dainprotocol/oauth2-token-manager");
11
- const hono_1 = require("hono");
12
- const node_server_1 = require("@hono/node-server");
13
- describe("OAuth Integration", () => {
14
- const privateKey = ed25519_1.ed25519.utils.randomPrivateKey();
15
- const publicKey = ed25519_1.ed25519.getPublicKey(privateKey);
16
- const clientPrivateKey = ed25519_1.ed25519.utils.randomPrivateKey();
17
- const agentAuth = new client_auth_1.DainClientAuth({
18
- privateKeyBase58: bs58_1.default.encode(clientPrivateKey),
19
- agentId: "agent-12",
20
- orgId: "org-12",
21
- });
22
- const mockTokenStore = new oauth2_token_manager_1.InMemoryStorageAdapter();
23
- let oauthServer;
24
- let oauthSdk;
25
- let mockOAuthProvider;
26
- beforeAll(async () => {
27
- // Create mock OAuth provider server
28
- const mockOAuthApp = new hono_1.Hono();
29
- // Add auth endpoint
30
- mockOAuthApp.get('/auth', (c) => {
31
- return c.redirect(c.req.query('redirect_uri') +
32
- '?code=test-code&state=' + c.req.query('state'));
33
- });
34
- mockOAuthApp.post('/token', async (c) => {
35
- const body = await c.req.parseBody();
36
- // Verify the expected OAuth token request
37
- if (body.grant_type === 'authorization_code' &&
38
- body.client_id === 'test-client-id' &&
39
- body.client_secret === 'test-client-secret' &&
40
- body.code === 'test-code') {
41
- return c.json({
42
- access_token: 'mock_access_token',
43
- token_type: 'Bearer',
44
- expires_in: 3600,
45
- refresh_token: 'mock_refresh_token',
46
- scope: 'test_scope',
47
- });
48
- }
49
- return c.json({ error: 'invalid_request' }, 400);
50
- });
51
- mockOAuthProvider = (0, node_server_1.serve)({
52
- fetch: mockOAuthApp.fetch,
53
- port: 4455
54
- });
55
- // Update the OAuth service config to use mock server
56
- const oauthService = (0, nodeService_1.defineDAINService)({
57
- metadata: {
58
- title: "Test OAuth Service",
59
- description: "A test OAuth service",
60
- version: "1.0.0",
61
- author: "Test Author",
62
- tags: ["test", "oauth"],
63
- },
64
- identity: {
65
- publicKey: bs58_1.default.encode(publicKey),
66
- agentId: "test-agent",
67
- orgId: "test-org",
68
- privateKey: bs58_1.default.encode(privateKey),
69
- },
70
- oauth2: {
71
- baseUrl: "http://localhost:4422",
72
- tokenStore: mockTokenStore,
73
- providers: {
74
- test_provider: {
75
- clientId: "test-client-id",
76
- clientSecret: "test-client-secret",
77
- authorizationUrl: "http://localhost:4455/auth", // Point to mock server
78
- tokenUrl: "http://localhost:4455/token", // Point to mock server
79
- scopes: ["test_scope"],
80
- reason: "Required for testing",
81
- requiredTools: ["test-oauth-tool"],
82
- onSuccess: async (agentId, tokens) => {
83
- console.log("OAuth success", agentId, tokens);
84
- },
85
- },
86
- },
87
- },
88
- tools: [
89
- (0, nodeService_1.createTool)({
90
- id: "test-oauth-tool",
91
- name: "Test OAuth Tool",
92
- description: "Tool that requires OAuth",
93
- input: zod_1.z.object({}),
94
- output: zod_1.z.object({ success: zod_1.z.boolean() }),
95
- pricing: { pricePerUse: 0.01, currency: "USD" },
96
- handler: async () => ({
97
- text: "OAuth test",
98
- data: { success: true },
99
- ui: null,
100
- }),
101
- }),
102
- ],
103
- });
104
- oauthServer = await oauthService.startNode({ port: 4422 });
105
- oauthSdk = new api_sdk_1.DainSDK("http://localhost:4422", agentAuth);
106
- await oauthSdk.initialize();
107
- });
108
- afterAll(async () => {
109
- if (oauthServer) {
110
- await oauthServer.shutdown();
111
- }
112
- if (mockOAuthProvider) {
113
- await new Promise((resolve) => {
114
- mockOAuthProvider.close(() => resolve(undefined));
115
- });
116
- }
117
- // Give a moment for all connections to close
118
- await new Promise(resolve => setTimeout(resolve, 100));
119
- });
120
- describe("Provider Management", () => {
121
- it("should list available OAuth providers", async () => {
122
- const providers = await oauthSdk.getOAuthProviders();
123
- expect(providers).toHaveLength(1);
124
- expect(providers[0].name).toBe("test_provider");
125
- expect(providers[0].config.reason).toBe("Required for testing");
126
- expect(providers[0].config.scopes).toEqual(["test_scope"]);
127
- expect(providers[0].config.requiredTools).toEqual(["test-oauth-tool"]);
128
- });
129
- it("should generate OAuth connect URL", async () => {
130
- const url = await oauthSdk.getOAuthConnectUrl("test_provider");
131
- expect(url).toContain("http://localhost:4455/auth");
132
- expect(url).toContain("client_id=test-client-id");
133
- expect(url).toContain("scope=test_scope");
134
- });
135
- it("should throw error for invalid provider", async () => {
136
- await expect(oauthSdk.getOAuthConnectUrl("invalid_provider"))
137
- .rejects
138
- .toThrow();
139
- });
140
- });
141
- describe("Tool Requirements", () => {
142
- it("should identify tools requiring OAuth", async () => {
143
- const requirements = await oauthSdk.getToolOAuthRequirements("test-oauth-tool");
144
- expect(requirements.required).toBe(true);
145
- expect(requirements.providers).toHaveLength(1);
146
- expect(requirements.providers[0].name).toBe("test_provider");
147
- expect(requirements.providers[0].reason).toBe("Required for testing");
148
- });
149
- it("should handle tools without OAuth requirements", async () => {
150
- const noOAuthTool = (0, nodeService_1.createTool)({
151
- id: "no-oauth-tool",
152
- name: "No OAuth Tool",
153
- description: "Tool that doesn't require OAuth",
154
- input: zod_1.z.object({}),
155
- output: zod_1.z.object({}),
156
- pricing: { pricePerUse: 0.01, currency: "USD" },
157
- handler: async () => ({
158
- text: "No OAuth",
159
- data: {},
160
- ui: null,
161
- }),
162
- });
163
- const service = (0, nodeService_1.defineDAINService)({
164
- metadata: {
165
- title: "Test OAuth Service",
166
- description: "A test OAuth service",
167
- version: "1.0.0",
168
- author: "Test Author",
169
- tags: ["test", "oauth"],
170
- },
171
- identity: {
172
- publicKey: bs58_1.default.encode(publicKey),
173
- agentId: "test-agent",
174
- orgId: "test-org",
175
- privateKey: bs58_1.default.encode(privateKey),
176
- },
177
- oauth2: {
178
- baseUrl: "http://localhost:4423",
179
- tokenStore: mockTokenStore,
180
- providers: {
181
- test_provider: {
182
- clientId: "test-client-id",
183
- clientSecret: "test-client-secret",
184
- authorizationUrl: "https://test.com/auth",
185
- tokenUrl: "https://test.com/token",
186
- scopes: ["test_scope"],
187
- reason: "Required for testing",
188
- requiredTools: ["test-oauth-tool"],
189
- onSuccess: async (agentId, tokens) => {
190
- console.log("OAuth success", agentId, tokens);
191
- },
192
- },
193
- },
194
- },
195
- tools: [(0, nodeService_1.createTool)({
196
- id: "test-oauth-tool",
197
- name: "Test OAuth Tool",
198
- description: "Tool that requires OAuth",
199
- input: zod_1.z.object({}),
200
- output: zod_1.z.object({ success: zod_1.z.boolean() }),
201
- pricing: { pricePerUse: 0.01, currency: "USD" },
202
- handler: async () => ({
203
- text: "OAuth test",
204
- data: { success: true },
205
- ui: null,
206
- }),
207
- }), noOAuthTool],
208
- });
209
- const newServer = await service.startNode({ port: 4423 });
210
- const newSdk = new api_sdk_1.DainSDK("http://localhost:4423", agentAuth);
211
- await newSdk.initialize();
212
- const requirements = await newSdk.getToolOAuthRequirements("no-oauth-tool");
213
- expect(requirements.required).toBe(false);
214
- expect(requirements.providers).toHaveLength(0);
215
- await newServer.shutdown();
216
- });
217
- });
218
- describe("Documentation", () => {
219
- it("should include OAuth requirements in documentation", async () => {
220
- const docs = await oauthSdk.getDocumentation();
221
- expect(docs).toContain("## OAuth Requirements");
222
- expect(docs).toContain("test_provider");
223
- expect(docs).toContain("Required for testing");
224
- expect(docs).toContain("test_scope");
225
- expect(docs).toContain("**OAuth Requirements:**");
226
- expect(docs).toContain("test_provider: Required for testing");
227
- });
228
- });
229
- describe("Token Management", () => {
230
- it("should check OAuth requirements before executing tool", async () => {
231
- // @ts-ignore - Accessing generated method
232
- await expect(oauthSdk.testOauthTool({}))
233
- .rejects
234
- .toThrow(/Missing required OAuth connections/);
235
- });
236
- it("should handle OAuth flow integration", async () => {
237
- // This test verifies the integration between the SDK and oauth2-token-manager
238
- // The actual OAuth flow is handled by the oauth2-token-manager library
239
- // Get OAuth URL
240
- const authUrl = await oauthSdk.getOAuthConnectUrl("test_provider");
241
- expect(authUrl).toContain("http://localhost:4455/auth");
242
- expect(authUrl).toContain("client_id=test-client-id");
243
- // Check initial state - should not be connected
244
- const requirements = await oauthSdk.getToolOAuthRequirements("test-oauth-tool");
245
- expect(requirements.providers[0].connected).toBe(false);
246
- // Note: Full OAuth flow testing would require simulating the entire OAuth dance
247
- // which is already tested in the oauth2-token-manager library
248
- });
249
- });
250
- describe("PKCE and Basic Auth", () => {
251
- let pkceServer;
252
- let pkceSdk;
253
- let pkceMockProvider;
254
- beforeAll(async () => {
255
- // Create mock OAuth provider with PKCE support
256
- const mockPKCEApp = new hono_1.Hono();
257
- // Add auth endpoint that validates PKCE parameters
258
- mockPKCEApp.get('/auth', (c) => {
259
- const codeChallenge = c.req.query('code_challenge');
260
- const codeChallengeMethod = c.req.query('code_challenge_method');
261
- // Verify PKCE parameters are present
262
- if (!codeChallenge || codeChallengeMethod !== 'S256') {
263
- return c.json({ error: 'invalid_request' }, 400);
264
- }
265
- return c.redirect(c.req.query('redirect_uri') +
266
- '?code=pkce-test-code&state=' + c.req.query('state'));
267
- });
268
- // Add token endpoint that validates PKCE code verifier and Basic Auth
269
- mockPKCEApp.post('/token', async (c) => {
270
- const authHeader = c.req.header('Authorization');
271
- const body = await c.req.parseBody();
272
- // Verify Basic Auth
273
- const expectedAuth = 'Basic ' + Buffer.from('pkce-client-id:pkce-client-secret').toString('base64');
274
- if (authHeader !== expectedAuth) {
275
- return c.json({ error: 'invalid_client' }, 401);
276
- }
277
- // Verify PKCE code verifier is present
278
- if (!body.code_verifier) {
279
- return c.json({ error: 'invalid_request' }, 400);
280
- }
281
- return c.json({
282
- access_token: 'pkce_access_token',
283
- token_type: 'Bearer',
284
- expires_in: 3600,
285
- refresh_token: 'pkce_refresh_token',
286
- scope: 'pkce_scope',
287
- });
288
- });
289
- pkceMockProvider = (0, node_server_1.serve)({
290
- fetch: mockPKCEApp.fetch,
291
- port: 4456
292
- });
293
- const pkcePrivateKey = ed25519_1.ed25519.utils.randomPrivateKey();
294
- const pkcePublicKey = ed25519_1.ed25519.getPublicKey(pkcePrivateKey);
295
- // Create service with PKCE and Basic Auth enabled
296
- const pkceService = (0, nodeService_1.defineDAINService)({
297
- metadata: {
298
- title: "PKCE OAuth Test Service",
299
- description: "Testing PKCE and Basic Auth",
300
- version: "1.0.0",
301
- author: "Test Author",
302
- tags: ["test", "oauth", "pkce"],
303
- },
304
- identity: {
305
- publicKey: bs58_1.default.encode(pkcePublicKey),
306
- privateKey: bs58_1.default.encode(pkcePrivateKey),
307
- agentId: "test-agent",
308
- orgId: "test-org",
309
- },
310
- oauth2: {
311
- baseUrl: "http://localhost:4424",
312
- tokenStore: new oauth2_token_manager_1.InMemoryStorageAdapter(),
313
- providers: {
314
- pkce_provider: {
315
- clientId: "pkce-client-id",
316
- clientSecret: "pkce-client-secret",
317
- authorizationUrl: "http://localhost:4456/auth",
318
- tokenUrl: "http://localhost:4456/token",
319
- scopes: ["pkce_scope"],
320
- reason: "Testing PKCE flow",
321
- requiredTools: ["pkce-test-tool"],
322
- usePKCE: true,
323
- useBasicAuth: true,
324
- },
325
- },
326
- },
327
- tools: [
328
- (0, nodeService_1.createTool)({
329
- id: "pkce-test-tool",
330
- name: "PKCE Test Tool",
331
- description: "Tool for testing PKCE flow",
332
- input: zod_1.z.object({}),
333
- output: zod_1.z.object({ success: zod_1.z.boolean() }),
334
- handler: async () => ({
335
- text: "PKCE test",
336
- data: { success: true },
337
- ui: null,
338
- }),
339
- }),
340
- ],
341
- });
342
- pkceServer = await pkceService.startNode({ port: 4424 });
343
- pkceSdk = new api_sdk_1.DainSDK("http://localhost:4424", agentAuth);
344
- await pkceSdk.initialize();
345
- });
346
- afterAll(async () => {
347
- if (pkceServer) {
348
- await pkceServer.shutdown();
349
- }
350
- if (pkceMockProvider) {
351
- await new Promise((resolve) => {
352
- pkceMockProvider.close(() => resolve(undefined));
353
- });
354
- }
355
- // Give a moment for all connections to close
356
- await new Promise(resolve => setTimeout(resolve, 100));
357
- });
358
- it("should generate auth URL with PKCE parameters", async () => {
359
- const url = await pkceSdk.getOAuthConnectUrl("pkce_provider");
360
- const urlParams = new URL(url).searchParams;
361
- expect(urlParams.get('code_challenge')).toBeTruthy();
362
- expect(urlParams.get('code_challenge_method')).toBe('S256');
363
- });
364
- it("should complete PKCE flow with Basic Auth", async () => {
365
- // This test verifies PKCE parameters are included in the auth URL
366
- // The actual PKCE flow is handled by the oauth2-token-manager library
367
- const url = await pkceSdk.getOAuthConnectUrl("pkce_provider");
368
- const urlParams = new URL(url).searchParams;
369
- // Verify PKCE parameters are present
370
- expect(urlParams.get('code_challenge')).toBeTruthy();
371
- expect(urlParams.get('code_challenge_method')).toBe('S256');
372
- // Verify initial state - should not be connected
373
- const requirements = await pkceSdk.getToolOAuthRequirements("pkce-test-tool");
374
- expect(requirements.providers[0].connected).toBe(false);
375
- });
376
- });
377
- });
378
- //# sourceMappingURL=oauth.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oauth.test.js","sourceRoot":"","sources":["../../src/__tests__/oauth.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,182 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const oauth2_token_manager_1 = require("@dainprotocol/oauth2-token-manager");
4
- describe('OAuth2Client Integration Tests', () => {
5
- let oauth2Client;
6
- let storage;
7
- beforeEach(() => {
8
- // Use in-memory storage for tests
9
- storage = new oauth2_token_manager_1.InMemoryStorageAdapter();
10
- oauth2Client = new oauth2_token_manager_1.OAuth2Client({
11
- storage,
12
- providers: {
13
- google: {
14
- clientId: 'test-client-id',
15
- clientSecret: 'test-client-secret',
16
- authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth',
17
- tokenUrl: 'https://oauth2.googleapis.com/token',
18
- redirectUri: 'http://localhost:3000/callback',
19
- scopes: ['email', 'profile'],
20
- extraAuthParams: {
21
- access_type: 'offline',
22
- prompt: 'consent'
23
- }
24
- }
25
- },
26
- autoRefresh: {
27
- enabled: true,
28
- refreshBuffer: 10,
29
- onRefreshError: (error, token) => {
30
- console.error('Refresh error:', error.message);
31
- }
32
- }
33
- });
34
- });
35
- describe('Token Storage', () => {
36
- it('should use the provided storage adapter', async () => {
37
- // Generate auth URL
38
- const { url, state } = await oauth2Client.authorize({
39
- provider: 'google',
40
- userId: 'agent123',
41
- email: 'agent123@dain.local'
42
- });
43
- expect(url).toContain('https://accounts.google.com/o/oauth2/v2/auth');
44
- expect(url).toContain('access_type=offline');
45
- expect(url).toContain('prompt=consent');
46
- expect(state).toBeDefined();
47
- });
48
- it('should save tokens to the provided storage', async () => {
49
- const mockToken = {
50
- accessToken: 'mock-access-token',
51
- refreshToken: 'mock-refresh-token',
52
- expiresAt: new Date(Date.now() + 3600000), // 1 hour
53
- tokenType: 'Bearer',
54
- scope: 'email profile'
55
- };
56
- // Save a token
57
- const saved = await storage.saveToken({
58
- provider: 'google',
59
- userId: 'agent123',
60
- email: 'agent123@dain.local',
61
- token: mockToken
62
- });
63
- expect(saved).toBeDefined();
64
- expect(saved.provider).toBe('google');
65
- expect(saved.userId).toBe('agent123');
66
- expect(saved.email).toBe('agent123@dain.local');
67
- });
68
- it('should query tokens with auto-refresh', async () => {
69
- // Save an expired token with refresh token
70
- const expiredToken = {
71
- accessToken: 'expired-access-token',
72
- refreshToken: 'valid-refresh-token',
73
- expiresAt: new Date(Date.now() - 3600000), // Expired 1 hour ago
74
- tokenType: 'Bearer',
75
- scope: 'email profile'
76
- };
77
- await storage.saveToken({
78
- provider: 'google',
79
- userId: 'agent123',
80
- email: 'agent123@dain.local',
81
- token: expiredToken
82
- });
83
- // Query tokens - should attempt refresh
84
- const tokens = await oauth2Client.queryTokens({
85
- userId: 'agent123',
86
- provider: 'google'
87
- });
88
- // Since we can't actually refresh in tests, the expired token would be filtered out
89
- expect(tokens).toEqual([]);
90
- });
91
- it('should work with agent ID to email mapping', async () => {
92
- const agentId = 'agent123';
93
- const dainEmail = `${agentId}@dain.local`;
94
- // Save a valid token
95
- const validToken = {
96
- accessToken: 'valid-access-token',
97
- refreshToken: 'valid-refresh-token',
98
- expiresAt: new Date(Date.now() + 3600000), // 1 hour from now
99
- tokenType: 'Bearer',
100
- scope: 'email profile'
101
- };
102
- await storage.saveToken({
103
- provider: 'google',
104
- userId: agentId,
105
- email: dainEmail,
106
- token: validToken
107
- });
108
- // Query by userId (agentId)
109
- const tokensByUser = await oauth2Client.queryTokens({
110
- userId: agentId
111
- });
112
- expect(tokensByUser).toHaveLength(1);
113
- expect(tokensByUser[0].userId).toBe(agentId);
114
- expect(tokensByUser[0].email).toBe(dainEmail);
115
- // Query by email
116
- const tokensByEmail = await oauth2Client.queryTokens({
117
- email: dainEmail
118
- });
119
- expect(tokensByEmail).toHaveLength(1);
120
- expect(tokensByEmail[0].userId).toBe(agentId);
121
- expect(tokensByEmail[0].email).toBe(dainEmail);
122
- // Get valid token
123
- const validTokenResult = await oauth2Client.getValidToken('google', dainEmail);
124
- expect(validTokenResult.accessToken).toBe('valid-access-token');
125
- });
126
- });
127
- describe('OAuth2Client Methods', () => {
128
- it('should expose all necessary methods', () => {
129
- // Check that all required methods exist
130
- expect(typeof oauth2Client.authorize).toBe('function');
131
- expect(typeof oauth2Client.handleCallback).toBe('function');
132
- expect(typeof oauth2Client.queryTokens).toBe('function');
133
- expect(typeof oauth2Client.getAccessToken).toBe('function');
134
- expect(typeof oauth2Client.getValidToken).toBe('function');
135
- expect(typeof oauth2Client.getTokensByUserId).toBe('function');
136
- expect(typeof oauth2Client.getTokensByEmail).toBe('function');
137
- expect(typeof oauth2Client.deleteToken).toBe('function');
138
- expect(typeof oauth2Client.cleanupExpiredTokens).toBe('function');
139
- });
140
- it('should include extraAuthParams in authorization URL', async () => {
141
- const { url } = await oauth2Client.authorize({
142
- provider: 'google',
143
- userId: 'agent123',
144
- email: 'agent123@dain.local'
145
- });
146
- const urlObj = new URL(url);
147
- expect(urlObj.searchParams.get('access_type')).toBe('offline');
148
- expect(urlObj.searchParams.get('prompt')).toBe('consent');
149
- expect(urlObj.searchParams.get('client_id')).toBe('test-client-id');
150
- expect(urlObj.searchParams.get('redirect_uri')).toBe('http://localhost:3000/callback');
151
- expect(urlObj.searchParams.get('scope')).toBe('email profile');
152
- });
153
- });
154
- describe('DrizzleStorageAdapter Compatibility', () => {
155
- it('should work with any storage adapter implementing the interface', async () => {
156
- // This test demonstrates that OAuth2Client works with any storage adapter
157
- // In production, this would be DrizzleStorageAdapter
158
- const customStorage = new oauth2_token_manager_1.InMemoryStorageAdapter();
159
- const clientWithCustomStorage = new oauth2_token_manager_1.OAuth2Client({
160
- storage: customStorage,
161
- providers: {
162
- google: {
163
- clientId: 'test-client-id',
164
- clientSecret: 'test-client-secret',
165
- authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth',
166
- tokenUrl: 'https://oauth2.googleapis.com/token',
167
- redirectUri: 'http://localhost:3000/callback',
168
- scopes: ['email', 'profile']
169
- }
170
- }
171
- });
172
- // Should work the same way
173
- const { url } = await clientWithCustomStorage.authorize({
174
- provider: 'google',
175
- userId: 'agent123',
176
- email: 'agent123@dain.local'
177
- });
178
- expect(url).toContain('https://accounts.google.com/o/oauth2/v2/auth');
179
- });
180
- });
181
- });
182
- //# sourceMappingURL=oauth2-client-integration.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oauth2-client-integration.test.js","sourceRoot":"","sources":["../../src/__tests__/oauth2-client-integration.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};