@better-auth/sso 1.4.0-beta.4 → 1.4.0-beta.6
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/.turbo/turbo-build.log +1 -1
- package/package.json +3 -3
- package/src/oidc.test.ts +93 -212
- package/tsconfig.json +0 -5
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @better-auth/sso@1.4.0-beta.
|
|
2
|
+
> @better-auth/sso@1.4.0-beta.6 build /home/runner/work/better-auth/better-auth/packages/sso
|
|
3
3
|
> unbuild
|
|
4
4
|
|
|
5
5
|
[info] Automatically detected entries: src/index, src/client [esm] [cjs] [dts]
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/sso",
|
|
3
3
|
"author": "Bereket Engida",
|
|
4
|
-
"version": "1.4.0-beta.
|
|
4
|
+
"version": "1.4.0-beta.6",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"body-parser": "^2.2.0",
|
|
59
59
|
"express": "^5.1.0",
|
|
60
60
|
"unbuild": "3.6.1",
|
|
61
|
-
"better-auth": "^1.4.0-beta.
|
|
61
|
+
"better-auth": "^1.4.0-beta.6"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"better-auth": "1.4.0-beta.
|
|
64
|
+
"better-auth": "1.4.0-beta.6"
|
|
65
65
|
},
|
|
66
66
|
"scripts": {
|
|
67
67
|
"test": "vitest",
|
package/src/oidc.test.ts
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
2
|
+
import { getTestInstanceMemory as getTestInstance } from "better-auth/test";
|
|
2
3
|
import { sso } from ".";
|
|
3
4
|
import { OAuth2Server } from "oauth2-mock-server";
|
|
4
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
5
|
-
import { organization } from "better-auth/plugins
|
|
6
|
-
import {
|
|
6
|
+
import { organization } from "better-auth/plugins";
|
|
7
|
+
import { createAuthClient } from "better-auth/client";
|
|
8
|
+
import { ssoClient } from "./client";
|
|
7
9
|
|
|
8
10
|
let server = new OAuth2Server();
|
|
9
11
|
|
|
10
12
|
describe("SSO", async () => {
|
|
11
|
-
const { auth, signInWithTestUser, customFetchImpl } =
|
|
12
|
-
await
|
|
13
|
+
const { auth, signInWithTestUser, customFetchImpl, cookieSetter } =
|
|
14
|
+
await getTestInstance({
|
|
13
15
|
plugins: [sso(), organization()],
|
|
14
16
|
});
|
|
15
17
|
|
|
18
|
+
const authClient = createAuthClient({
|
|
19
|
+
plugins: [ssoClient()],
|
|
20
|
+
baseURL: "http://localhost:3000",
|
|
21
|
+
fetchOptions: {
|
|
22
|
+
customFetchImpl,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
16
26
|
beforeAll(async () => {
|
|
17
27
|
await server.issuer.keys.generate("RS256");
|
|
18
28
|
server.issuer.on;
|
|
@@ -57,7 +67,7 @@ describe("SSO", async () => {
|
|
|
57
67
|
});
|
|
58
68
|
|
|
59
69
|
if (!location) throw new Error("No redirect location found");
|
|
60
|
-
|
|
70
|
+
const newHeaders = new Headers();
|
|
61
71
|
let callbackURL = "";
|
|
62
72
|
await betterFetch(location, {
|
|
63
73
|
method: "GET",
|
|
@@ -65,10 +75,11 @@ describe("SSO", async () => {
|
|
|
65
75
|
headers,
|
|
66
76
|
onError(context) {
|
|
67
77
|
callbackURL = context.response.headers.get("location") || "";
|
|
78
|
+
cookieSetter(newHeaders)(context);
|
|
68
79
|
},
|
|
69
80
|
});
|
|
70
81
|
|
|
71
|
-
return callbackURL;
|
|
82
|
+
return { callbackURL, headers: newHeaders };
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
it("should register a new SSO provider", async () => {
|
|
@@ -147,122 +158,76 @@ describe("SSO", async () => {
|
|
|
147
158
|
});
|
|
148
159
|
|
|
149
160
|
it("should sign in with SSO provider with email matching", async () => {
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
161
|
+
const headers = new Headers();
|
|
162
|
+
const res = await authClient.signIn.sso({
|
|
163
|
+
email: "my-email@localhost.com",
|
|
164
|
+
callbackURL: "/dashboard",
|
|
165
|
+
fetchOptions: {
|
|
166
|
+
throw: true,
|
|
167
|
+
onSuccess: cookieSetter(headers),
|
|
154
168
|
},
|
|
155
169
|
});
|
|
156
170
|
expect(res.url).toContain("http://localhost:8080/authorize");
|
|
157
171
|
expect(res.url).toContain(
|
|
158
172
|
"redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fsso%2Fcallback%2Ftest",
|
|
159
173
|
);
|
|
160
|
-
const
|
|
161
|
-
const callbackURL = await simulateOAuthFlow(res.url, headers);
|
|
174
|
+
const { callbackURL } = await simulateOAuthFlow(res.url, headers);
|
|
162
175
|
expect(callbackURL).toContain("/dashboard");
|
|
163
176
|
});
|
|
164
177
|
|
|
165
178
|
it("should sign in with SSO provider with domain", async () => {
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
179
|
+
const headers = new Headers();
|
|
180
|
+
const res = await authClient.signIn.sso({
|
|
181
|
+
email: "my-email@test.com",
|
|
182
|
+
domain: "localhost.com",
|
|
183
|
+
callbackURL: "/dashboard",
|
|
184
|
+
fetchOptions: {
|
|
185
|
+
throw: true,
|
|
186
|
+
onSuccess: cookieSetter(headers),
|
|
171
187
|
},
|
|
172
188
|
});
|
|
173
189
|
expect(res.url).toContain("http://localhost:8080/authorize");
|
|
174
190
|
expect(res.url).toContain(
|
|
175
191
|
"redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fsso%2Fcallback%2Ftest",
|
|
176
192
|
);
|
|
177
|
-
const
|
|
178
|
-
const callbackURL = await simulateOAuthFlow(res.url, headers);
|
|
193
|
+
const { callbackURL } = await simulateOAuthFlow(res.url, headers);
|
|
179
194
|
expect(callbackURL).toContain("/dashboard");
|
|
180
195
|
});
|
|
181
196
|
|
|
182
197
|
it("should sign in with SSO provider with providerId", async () => {
|
|
183
|
-
const res = await auth.api.signInSSO({
|
|
184
|
-
body: {
|
|
185
|
-
providerId: "test",
|
|
186
|
-
callbackURL: "/dashboard",
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
expect(res.url).toContain("http://localhost:8080/authorize");
|
|
190
|
-
expect(res.url).toContain(
|
|
191
|
-
"redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fsso%2Fcallback%2Ftest",
|
|
192
|
-
);
|
|
193
198
|
const headers = new Headers();
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const { auth, signInWithTestUser, customFetchImpl } =
|
|
201
|
-
await getTestInstanceMemory({
|
|
202
|
-
plugins: [
|
|
203
|
-
sso({
|
|
204
|
-
defaultSSO: [
|
|
205
|
-
{
|
|
206
|
-
domain: "localhost.com",
|
|
207
|
-
providerId: "default-test",
|
|
208
|
-
oidcConfig: {
|
|
209
|
-
issuer: "http://localhost:8080",
|
|
210
|
-
clientId: "test",
|
|
211
|
-
clientSecret: "test",
|
|
212
|
-
authorizationEndpoint: "http://localhost:8080/authorize",
|
|
213
|
-
tokenEndpoint: "http://localhost:8080/token",
|
|
214
|
-
jwksEndpoint: "http://localhost:8080/jwks",
|
|
215
|
-
discoveryEndpoint:
|
|
216
|
-
"http://localhost:8080/.well-known/openid-configuration",
|
|
217
|
-
pkce: true,
|
|
218
|
-
mapping: {
|
|
219
|
-
id: "sub",
|
|
220
|
-
email: "email",
|
|
221
|
-
emailVerified: "email_verified",
|
|
222
|
-
name: "name",
|
|
223
|
-
image: "picture",
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
],
|
|
228
|
-
}),
|
|
229
|
-
organization(),
|
|
230
|
-
],
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it("should use default SSO provider from array when no provider found in database using providerId", async () => {
|
|
234
|
-
const res = await auth.api.signInSSO({
|
|
235
|
-
body: {
|
|
236
|
-
providerId: "default-test",
|
|
237
|
-
callbackURL: "/dashboard",
|
|
199
|
+
const res = await authClient.signIn.sso({
|
|
200
|
+
providerId: "test",
|
|
201
|
+
callbackURL: "/dashboard",
|
|
202
|
+
fetchOptions: {
|
|
203
|
+
throw: true,
|
|
204
|
+
onSuccess: cookieSetter(headers),
|
|
238
205
|
},
|
|
239
206
|
});
|
|
240
207
|
expect(res.url).toContain("http://localhost:8080/authorize");
|
|
241
208
|
expect(res.url).toContain(
|
|
242
|
-
"redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fsso%2Fcallback%
|
|
209
|
+
"redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fsso%2Fcallback%2Ftest",
|
|
243
210
|
);
|
|
244
|
-
});
|
|
245
211
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
body: {
|
|
249
|
-
email: "test@localhost.com",
|
|
250
|
-
callbackURL: "/dashboard",
|
|
251
|
-
},
|
|
252
|
-
});
|
|
253
|
-
expect(res.url).toContain("http://localhost:8080/authorize");
|
|
254
|
-
expect(res.url).toContain(
|
|
255
|
-
"redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fsso%2Fcallback%2Fdefault-test",
|
|
256
|
-
);
|
|
212
|
+
const { callbackURL } = await simulateOAuthFlow(res.url, headers);
|
|
213
|
+
expect(callbackURL).toContain("/dashboard");
|
|
257
214
|
});
|
|
258
215
|
});
|
|
259
216
|
|
|
260
217
|
describe("SSO disable implicit sign in", async () => {
|
|
261
|
-
const { auth, signInWithTestUser, customFetchImpl } =
|
|
262
|
-
await
|
|
218
|
+
const { auth, signInWithTestUser, customFetchImpl, cookieSetter } =
|
|
219
|
+
await getTestInstance({
|
|
263
220
|
plugins: [sso({ disableImplicitSignUp: true }), organization()],
|
|
264
221
|
});
|
|
265
222
|
|
|
223
|
+
const authClient = createAuthClient({
|
|
224
|
+
plugins: [ssoClient()],
|
|
225
|
+
baseURL: "http://localhost:3000",
|
|
226
|
+
fetchOptions: {
|
|
227
|
+
customFetchImpl,
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
|
|
266
231
|
beforeAll(async () => {
|
|
267
232
|
await server.issuer.keys.generate("RS256");
|
|
268
233
|
server.issuer.on;
|
|
@@ -307,7 +272,7 @@ describe("SSO disable implicit sign in", async () => {
|
|
|
307
272
|
});
|
|
308
273
|
|
|
309
274
|
if (!location) throw new Error("No redirect location found");
|
|
310
|
-
|
|
275
|
+
const newHeaders = new Headers(headers);
|
|
311
276
|
let callbackURL = "";
|
|
312
277
|
await betterFetch(location, {
|
|
313
278
|
method: "GET",
|
|
@@ -315,10 +280,11 @@ describe("SSO disable implicit sign in", async () => {
|
|
|
315
280
|
headers,
|
|
316
281
|
onError(context) {
|
|
317
282
|
callbackURL = context.response.headers.get("location") || "";
|
|
283
|
+
cookieSetter(newHeaders)(context);
|
|
318
284
|
},
|
|
319
285
|
});
|
|
320
286
|
|
|
321
|
-
return callbackURL;
|
|
287
|
+
return { callbackURL, headers: newHeaders };
|
|
322
288
|
}
|
|
323
289
|
|
|
324
290
|
it("should register a new SSO provider", async () => {
|
|
@@ -369,150 +335,61 @@ describe("SSO disable implicit sign in", async () => {
|
|
|
369
335
|
userId: expect.any(String),
|
|
370
336
|
});
|
|
371
337
|
});
|
|
372
|
-
it("should not allow creating a provider if limit is set to 0", async () => {
|
|
373
|
-
const { auth, signInWithTestUser } = await getTestInstanceMemory({
|
|
374
|
-
plugins: [sso({ providersLimit: 0 })],
|
|
375
|
-
});
|
|
376
|
-
const { headers } = await signInWithTestUser();
|
|
377
|
-
await expect(
|
|
378
|
-
auth.api.registerSSOProvider({
|
|
379
|
-
body: {
|
|
380
|
-
issuer: server.issuer.url!,
|
|
381
|
-
domain: "localhost.com",
|
|
382
|
-
oidcConfig: {
|
|
383
|
-
clientId: "test",
|
|
384
|
-
clientSecret: "test",
|
|
385
|
-
},
|
|
386
|
-
providerId: "test",
|
|
387
|
-
},
|
|
388
|
-
headers,
|
|
389
|
-
}),
|
|
390
|
-
).rejects.toMatchObject({
|
|
391
|
-
status: "FORBIDDEN",
|
|
392
|
-
body: { message: "SSO provider registration is disabled" },
|
|
393
|
-
});
|
|
394
|
-
});
|
|
395
|
-
it("should not allow creating a provider if limit is reached", async () => {
|
|
396
|
-
const { auth, signInWithTestUser } = await getTestInstanceMemory({
|
|
397
|
-
plugins: [sso({ providersLimit: 1 })],
|
|
398
|
-
});
|
|
399
|
-
const { headers } = await signInWithTestUser();
|
|
400
|
-
|
|
401
|
-
await auth.api.registerSSOProvider({
|
|
402
|
-
body: {
|
|
403
|
-
issuer: server.issuer.url!,
|
|
404
|
-
domain: "localhost.com",
|
|
405
|
-
oidcConfig: {
|
|
406
|
-
clientId: "test",
|
|
407
|
-
clientSecret: "test",
|
|
408
|
-
},
|
|
409
|
-
providerId: "test-1",
|
|
410
|
-
},
|
|
411
|
-
headers,
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
await expect(
|
|
415
|
-
auth.api.registerSSOProvider({
|
|
416
|
-
body: {
|
|
417
|
-
issuer: server.issuer.url!,
|
|
418
|
-
domain: "localhost.com",
|
|
419
|
-
oidcConfig: {
|
|
420
|
-
clientId: "test",
|
|
421
|
-
clientSecret: "test",
|
|
422
|
-
},
|
|
423
|
-
providerId: "test-2",
|
|
424
|
-
},
|
|
425
|
-
headers,
|
|
426
|
-
}),
|
|
427
|
-
).rejects.toMatchObject({
|
|
428
|
-
status: "FORBIDDEN",
|
|
429
|
-
body: {
|
|
430
|
-
message: "You have reached the maximum number of SSO providers",
|
|
431
|
-
},
|
|
432
|
-
});
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
it("should not allow creating a provider if limit from function is reached", async () => {
|
|
436
|
-
const { auth, signInWithTestUser } = await getTestInstanceMemory({
|
|
437
|
-
plugins: [sso({ providersLimit: async () => 1 })],
|
|
438
|
-
});
|
|
439
|
-
const { headers } = await signInWithTestUser();
|
|
440
|
-
|
|
441
|
-
await auth.api.registerSSOProvider({
|
|
442
|
-
body: {
|
|
443
|
-
issuer: server.issuer.url!,
|
|
444
|
-
domain: "localhost.com",
|
|
445
|
-
oidcConfig: {
|
|
446
|
-
clientId: "test",
|
|
447
|
-
clientSecret: "test",
|
|
448
|
-
},
|
|
449
|
-
providerId: "test-1",
|
|
450
|
-
},
|
|
451
|
-
headers,
|
|
452
|
-
});
|
|
453
338
|
|
|
454
|
-
await expect(
|
|
455
|
-
auth.api.registerSSOProvider({
|
|
456
|
-
body: {
|
|
457
|
-
issuer: server.issuer.url!,
|
|
458
|
-
domain: "localhost.com",
|
|
459
|
-
oidcConfig: {
|
|
460
|
-
clientId: "test",
|
|
461
|
-
clientSecret: "test",
|
|
462
|
-
},
|
|
463
|
-
providerId: "test-2",
|
|
464
|
-
},
|
|
465
|
-
headers,
|
|
466
|
-
}),
|
|
467
|
-
).rejects.toMatchObject({
|
|
468
|
-
status: "FORBIDDEN",
|
|
469
|
-
body: {
|
|
470
|
-
message: "You have reached the maximum number of SSO providers",
|
|
471
|
-
},
|
|
472
|
-
});
|
|
473
|
-
});
|
|
474
339
|
it("should not create user with SSO provider when sign ups are disabled", async () => {
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
340
|
+
const headers = new Headers();
|
|
341
|
+
const res = await authClient.signIn.sso({
|
|
342
|
+
email: "my-email@localhost.com",
|
|
343
|
+
callbackURL: "/dashboard",
|
|
344
|
+
fetchOptions: {
|
|
345
|
+
throw: true,
|
|
346
|
+
onSuccess: cookieSetter(headers),
|
|
479
347
|
},
|
|
480
348
|
});
|
|
481
349
|
expect(res.url).toContain("http://localhost:8080/authorize");
|
|
482
350
|
expect(res.url).toContain(
|
|
483
351
|
"redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fsso%2Fcallback%2Ftest",
|
|
484
352
|
);
|
|
485
|
-
const
|
|
486
|
-
const callbackURL = await simulateOAuthFlow(res.url, headers);
|
|
353
|
+
const { callbackURL } = await simulateOAuthFlow(res.url, headers);
|
|
487
354
|
expect(callbackURL).toContain(
|
|
488
355
|
"/api/auth/error/error?error=signup disabled",
|
|
489
356
|
);
|
|
490
357
|
});
|
|
491
358
|
|
|
492
359
|
it("should create user with SSO provider when sign ups are disabled but sign up is requested", async () => {
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
360
|
+
const headers = new Headers();
|
|
361
|
+
const res = await authClient.signIn.sso({
|
|
362
|
+
email: "my-email@localhost.com",
|
|
363
|
+
callbackURL: "/dashboard",
|
|
364
|
+
requestSignUp: true,
|
|
365
|
+
fetchOptions: {
|
|
366
|
+
throw: true,
|
|
367
|
+
onSuccess: cookieSetter(headers),
|
|
498
368
|
},
|
|
499
369
|
});
|
|
500
370
|
expect(res.url).toContain("http://localhost:8080/authorize");
|
|
501
371
|
expect(res.url).toContain(
|
|
502
372
|
"redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fsso%2Fcallback%2Ftest",
|
|
503
373
|
);
|
|
504
|
-
const
|
|
505
|
-
const callbackURL = await simulateOAuthFlow(res.url, headers);
|
|
374
|
+
const { callbackURL } = await simulateOAuthFlow(res.url, headers);
|
|
506
375
|
expect(callbackURL).toContain("/dashboard");
|
|
507
376
|
});
|
|
508
377
|
});
|
|
509
378
|
|
|
510
379
|
describe("provisioning", async (ctx) => {
|
|
511
|
-
const { auth, signInWithTestUser, customFetchImpl } =
|
|
512
|
-
await
|
|
380
|
+
const { auth, signInWithTestUser, customFetchImpl, cookieSetter } =
|
|
381
|
+
await getTestInstance({
|
|
513
382
|
plugins: [sso(), organization()],
|
|
514
383
|
});
|
|
515
384
|
|
|
385
|
+
const authClient = createAuthClient({
|
|
386
|
+
plugins: [ssoClient()],
|
|
387
|
+
baseURL: "http://localhost:3000",
|
|
388
|
+
fetchOptions: {
|
|
389
|
+
customFetchImpl,
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
|
|
516
393
|
beforeAll(async () => {
|
|
517
394
|
await server.issuer.keys.generate("RS256");
|
|
518
395
|
server.issuer.on;
|
|
@@ -540,12 +417,14 @@ describe("provisioning", async (ctx) => {
|
|
|
540
417
|
if (!location) throw new Error("No redirect location found");
|
|
541
418
|
|
|
542
419
|
let callbackURL = "";
|
|
420
|
+
const newHeaders = new Headers();
|
|
543
421
|
await betterFetch(location, {
|
|
544
422
|
method: "GET",
|
|
545
423
|
customFetchImpl: fetchImpl || customFetchImpl,
|
|
546
424
|
headers,
|
|
547
425
|
onError(context) {
|
|
548
426
|
callbackURL = context.response.headers.get("location") || "";
|
|
427
|
+
cookieSetter(newHeaders)(context);
|
|
549
428
|
},
|
|
550
429
|
});
|
|
551
430
|
|
|
@@ -605,18 +484,20 @@ describe("provisioning", async (ctx) => {
|
|
|
605
484
|
expect(provider).toMatchObject({
|
|
606
485
|
organizationId: organization?.id,
|
|
607
486
|
});
|
|
608
|
-
|
|
609
|
-
const res = await
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
487
|
+
const newHeaders = new Headers();
|
|
488
|
+
const res = await authClient.signIn.sso({
|
|
489
|
+
email: "my-email@localhost.com",
|
|
490
|
+
callbackURL: "/dashboard",
|
|
491
|
+
fetchOptions: {
|
|
492
|
+
onSuccess: cookieSetter(newHeaders),
|
|
493
|
+
throw: true,
|
|
613
494
|
},
|
|
614
495
|
});
|
|
615
496
|
expect(res.url).toContain("http://localhost:8080/authorize");
|
|
616
497
|
expect(res.url).toContain(
|
|
617
498
|
"redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fsso%2Fcallback%2Ftest",
|
|
618
499
|
);
|
|
619
|
-
|
|
500
|
+
|
|
620
501
|
const callbackURL = await simulateOAuthFlow(res.url, newHeaders);
|
|
621
502
|
expect(callbackURL).toContain("/dashboard");
|
|
622
503
|
const org = await auth.api.getFullOrganization({
|