@supertokens-plugins/rownd-nodejs 0.2.1 → 0.3.0-beta.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.
@@ -1,790 +0,0 @@
1
- import express from "express";
2
- import {
3
- describe,
4
- it,
5
- expect,
6
- afterEach,
7
- beforeEach,
8
- beforeAll,
9
- afterAll,
10
- vi,
11
- } from "vitest";
12
- import SuperTokens from "supertokens-node";
13
- import Session from "supertokens-node/recipe/session";
14
- import UserMetadata, {
15
- getUserMetadata,
16
- } from "supertokens-node/recipe/usermetadata";
17
- import Passwordless from "supertokens-node/recipe/passwordless";
18
- import EmailPassword from "supertokens-node/recipe/emailpassword";
19
- import ThirdParty from "supertokens-node/recipe/thirdparty";
20
- import AccountLinking from "supertokens-node/recipe/accountlinking";
21
- import { middleware, errorHandler } from "supertokens-node/framework/express";
22
- import { ProcessState } from "supertokens-node/lib/build/processState";
23
- import SuperTokensRaw from "supertokens-node/lib/build/supertokens";
24
- import SessionRaw from "supertokens-node/lib/build/recipe/session/recipe";
25
- import UserMetadataRaw from "supertokens-node/lib/build/recipe/usermetadata/recipe";
26
- import UserRolesRaw from "supertokens-node/lib/build/recipe/userroles/recipe";
27
- import AccountLinkingRaw from "supertokens-node/lib/build/recipe/accountlinking/recipe";
28
- import EmailPasswordRaw from "supertokens-node/lib/build/recipe/emailpassword/recipe";
29
- import ThirdPartyRaw from "supertokens-node/lib/build/recipe/thirdparty/recipe";
30
- import PasswordlessRaw from "supertokens-node/lib/build/recipe/passwordless/recipe";
31
- import MultitenancyRaw from "supertokens-node/lib/build/recipe/multitenancy/recipe";
32
- import { NormalisedURLDomain } from "supertokens-node/lib/build/normalisedURLDomain";
33
- import { Querier } from "supertokens-node/lib/build/querier";
34
- import { Server } from "http";
35
- import crypto from "crypto";
36
- import { GenericContainer, StartedTestContainer, Wait } from "testcontainers";
37
- import { Network, StartedNetwork } from "testcontainers";
38
-
39
- import { init } from "./plugin";
40
- import { HANDLE_BASE_PATH } from "./constants";
41
- import { RowndPluginConfig, RowndTelemetryClient } from "./types";
42
- import { ROWND_PLUGIN_ERROR_MESSAGES } from "./errors";
43
- import { mapRowndUserToSuperTokens } from "./pluginImplementation";
44
-
45
- let testPORT = 30001;
46
-
47
- const mockRowndClient = {
48
- validateToken: vi.fn(),
49
- fetchUserInfo: vi.fn(),
50
- };
51
-
52
- vi.mock("@rownd/node", () => ({
53
- createInstance: () => mockRowndClient,
54
- }));
55
-
56
- describe("rownd-nodejs plugin", () => {
57
- let server: Server | undefined;
58
- let container: StartedTestContainer;
59
- let postgresContainer: StartedTestContainer;
60
- let network: StartedNetwork;
61
- let coreConnectionURI: string;
62
-
63
- beforeAll(async () => {
64
- network = await new Network().start();
65
- postgresContainer = await new GenericContainer("postgres:14")
66
- .withNetwork(network)
67
- .withNetworkAliases("postgres")
68
- .withEnvironment({
69
- POSTGRES_USER: "supertokens",
70
- POSTGRES_PASSWORD: "somepassword",
71
- POSTGRES_DB: "supertokens",
72
- })
73
- .withExposedPorts(5432)
74
- .withWaitStrategy(
75
- Wait.forLogMessage("database system is ready to accept connections"),
76
- )
77
- .start();
78
-
79
- container = await new GenericContainer("supertokens/supertokens-postgresql")
80
- .withNetwork(network)
81
- .withEnvironment({
82
- POSTGRESQL_CONNECTION_URI:
83
- "postgresql://supertokens:somepassword@postgres:5432/supertokens",
84
- // LOG_LEVEL: "DEBUG",
85
- // INFO_LOG_PATH: "null",
86
- // ERROR_LOG_PATH: "null",
87
- })
88
- .withExposedPorts(3567)
89
- .withWaitStrategy(Wait.forHttp("/hello", 3567))
90
- .start();
91
-
92
- // const stream = await container.logs();
93
- // stream.on("data", (line) => console.log(line));
94
-
95
- const mappedPort = container.getMappedPort(3567);
96
- coreConnectionURI = `http://${container.getHost()}:${mappedPort}`;
97
- }, 120000);
98
-
99
- afterAll(async () => {
100
- if (container) {
101
- await container.stop();
102
- }
103
- if (postgresContainer) {
104
- await postgresContainer.stop();
105
- }
106
- if (network) {
107
- await network.stop();
108
- }
109
- });
110
-
111
- afterEach(async () => {
112
- if (server) {
113
- await new Promise((resolve) => server!.close(resolve));
114
- }
115
- resetST();
116
- });
117
-
118
- beforeEach(() => {
119
- resetST();
120
- vi.clearAllMocks();
121
- vi.restoreAllMocks();
122
- });
123
-
124
- describe("mapRowndUserToSuperTokens", () => {
125
- it("throws when the Rownd payload has no data object", () => {
126
- expect(() =>
127
- mapRowndUserToSuperTokens({ app_user_id: "rownd-no-data" } as any),
128
- ).toThrowError(new Error("Rownd user has no user_id"));
129
- });
130
-
131
- it("throws when data.user_id is missing", () => {
132
- expect(() =>
133
- mapRowndUserToSuperTokens({
134
- app_user_id: "rownd-missing-user-id",
135
- data: { email: "missing-user-id@example.com" },
136
- verified_data: { email: true },
137
- } as any),
138
- ).toThrowError(new Error("Rownd user has no user_id"));
139
- });
140
-
141
- it("throws when a google user is missing email", () => {
142
- expect(() =>
143
- mapRowndUserToSuperTokens({
144
- data: {
145
- user_id: "rownd-google-missing-email",
146
- google_id: "google-user-id",
147
- },
148
- verified_data: { google_id: true },
149
- } as any),
150
- ).toThrowError(new Error("Rownd Google user is missing email"));
151
- });
152
-
153
- it("throws when an apple user is missing email", () => {
154
- expect(() =>
155
- mapRowndUserToSuperTokens({
156
- data: {
157
- user_id: "rownd-apple-missing-email",
158
- apple_id: "apple-user-id",
159
- },
160
- verified_data: { apple_id: true },
161
- } as any),
162
- ).toThrowError(new Error("Rownd Apple user is missing email"));
163
- });
164
-
165
- it("throws when no supported login method can be derived", () => {
166
- expect(() =>
167
- mapRowndUserToSuperTokens({
168
- data: { user_id: "rownd-no-login-method" },
169
- verified_data: {},
170
- } as any),
171
- ).toThrowError(
172
- new Error("No valid login methods found in Rownd user data"),
173
- );
174
- });
175
-
176
- it("throws a type error when verified_data is missing for an otherwise valid email user", () => {
177
- expect(
178
- mapRowndUserToSuperTokens({
179
- data: {
180
- user_id: "rownd-missing-verified-data",
181
- email: "missing-verified-data@example.com",
182
- },
183
- } as any),
184
- ).toEqual({
185
- externalUserId: "rownd-missing-verified-data",
186
- loginMethods: [
187
- {
188
- recipeId: "passwordless",
189
- email: "missing-verified-data@example.com",
190
- isVerified: false,
191
- },
192
- ],
193
- userMetadata: {
194
- data: {
195
- user_id: "rownd-missing-verified-data",
196
- email: "missing-verified-data@example.com",
197
- },
198
- meta: {},
199
- verified_data: {},
200
- attributes: {},
201
- rownd_migrated: true,
202
- rownd_user_id: "rownd-missing-verified-data",
203
- },
204
- });
205
- });
206
-
207
- it("falls back missing metadata containers to empty objects", () => {
208
- expect(
209
- mapRowndUserToSuperTokens({
210
- data: {
211
- user_id: "rownd-metadata-fallback",
212
- email: "metadata-fallback@example.com",
213
- },
214
- verified_data: {},
215
- } as any),
216
- ).toEqual({
217
- externalUserId: "rownd-metadata-fallback",
218
- loginMethods: [
219
- {
220
- recipeId: "passwordless",
221
- email: "metadata-fallback@example.com",
222
- isVerified: false,
223
- },
224
- ],
225
- userMetadata: {
226
- data: {
227
- user_id: "rownd-metadata-fallback",
228
- email: "metadata-fallback@example.com",
229
- },
230
- meta: {},
231
- verified_data: {},
232
- attributes: {},
233
- rownd_migrated: true,
234
- rownd_user_id: "rownd-metadata-fallback",
235
- },
236
- });
237
- });
238
- });
239
-
240
- describe("user migration", () => {
241
- it("migrate user successfully", async () => {
242
- const telemetryClient: RowndTelemetryClient = {
243
- recordEvent: vi.fn(),
244
- };
245
- const { server: s, port } = await setup(coreConnectionURI, {
246
- telemetry: {
247
- provider: "custom",
248
- factory: () => telemetryClient,
249
- },
250
- });
251
- server = s;
252
- testPORT = port;
253
- const rowndUser = {
254
- app_user_id: "rownd-user-1",
255
- data: {
256
- user_id: "rownd-user-1",
257
- email: "test@example.com",
258
- },
259
- verified_data: {
260
- email: true,
261
- },
262
- };
263
- mockRowndClient.validateToken.mockResolvedValue({
264
- user_id: "rownd-user-1",
265
- });
266
- mockRowndClient.fetchUserInfo.mockResolvedValue(rowndUser);
267
-
268
- const res = await fetch(
269
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
270
- {
271
- method: "POST",
272
- headers: {
273
- Authorization: "Bearer some-token",
274
- },
275
- },
276
- );
277
- const body = await res.json();
278
- expect(res.status).toBe(200);
279
- expect(body).toEqual({ status: "OK" });
280
-
281
- const migratedUser = await getMigratedUserByRowndUserId(
282
- rowndUser.app_user_id,
283
- );
284
- expect(migratedUser).toBeDefined();
285
- const user = migratedUser!.user;
286
- expect(user).toBeDefined();
287
- expect(user?.loginMethods.length).toBe(1);
288
- expect(user?.loginMethods[0].recipeId).toBe("passwordless");
289
- expect(user?.loginMethods[0].email).toBe(rowndUser.data.email);
290
-
291
- const metadata = migratedUser!.metadata;
292
- expect(metadata.metadata).toEqual(
293
- expect.objectContaining({
294
- data: expect.objectContaining({
295
- email: rowndUser.data.email,
296
- }),
297
- rownd_migrated: true,
298
- rownd_user_id: rowndUser.app_user_id,
299
- }),
300
- );
301
- expect(telemetryClient.recordEvent).toHaveBeenCalledWith(
302
- expect.objectContaining({
303
- outcome: "success",
304
- rowndUserId: rowndUser.app_user_id,
305
- superTokensUserId: expect.any(String),
306
- }),
307
- );
308
- });
309
-
310
- it("migrate user with custom metadata successfully", async () => {
311
- const { server: s, port } = await setup(coreConnectionURI);
312
- server = s;
313
- testPORT = port;
314
- mockRowndClient.validateToken.mockResolvedValue({
315
- user_id: "rownd-user-2",
316
- });
317
- mockRowndClient.fetchUserInfo.mockResolvedValue({
318
- app_user_id: "rownd-user-2",
319
- data: {
320
- user_id: "rownd-user-2",
321
- email: "test2@example.com",
322
- first_name: "John",
323
- last_name: "Doe",
324
- },
325
- verified_data: { email: true },
326
- });
327
-
328
- await fetch(`http://localhost:${testPORT}/auth/plugin/rownd/migrate`, {
329
- method: "POST",
330
- headers: { Authorization: "Bearer some-token" },
331
- });
332
-
333
- const migratedUser = await getMigratedUserByRowndUserId("rownd-user-2");
334
- expect(migratedUser).toBeDefined();
335
- const metadata = migratedUser!.metadata;
336
- expect(metadata.metadata).toEqual(
337
- expect.objectContaining({
338
- data: expect.objectContaining({
339
- first_name: "John",
340
- last_name: "Doe",
341
- }),
342
- rownd_migrated: true,
343
- }),
344
- );
345
- });
346
-
347
- it("migrate a passwordles auth user", async () => {
348
- const { server: s, port } = await setup(coreConnectionURI);
349
- server = s;
350
- testPORT = port;
351
- mockRowndClient.validateToken.mockResolvedValue({
352
- user_id: "rownd-user-phone",
353
- });
354
- mockRowndClient.fetchUserInfo.mockResolvedValue({
355
- app_user_id: "rownd-user-phone",
356
- data: { user_id: "rownd-user-phone", phone_number: "+1234567890" },
357
- verified_data: { phone_number: true },
358
- });
359
-
360
- const res = await fetch(
361
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
362
- {
363
- method: "POST",
364
- headers: { Authorization: "Bearer some-token" },
365
- },
366
- );
367
- expect(await res.json()).toEqual({ status: "OK" });
368
-
369
- const migratedUser =
370
- await getMigratedUserByRowndUserId("rownd-user-phone");
371
- expect(migratedUser).toBeDefined();
372
- const user = migratedUser!.user;
373
- expect(user?.loginMethods[0].phoneNumber).toBe("+1234567890");
374
- });
375
-
376
- it("migrate a google auth user", async () => {
377
- const { server: s, port } = await setup(coreConnectionURI);
378
- server = s;
379
- testPORT = port;
380
- mockRowndClient.validateToken.mockResolvedValue({
381
- user_id: "rownd-user-google",
382
- });
383
- mockRowndClient.fetchUserInfo.mockResolvedValue({
384
- app_user_id: "rownd-user-google",
385
- data: {
386
- user_id: "rownd-user-google",
387
- google_id: "g-123",
388
- email: "g@example.com",
389
- },
390
- verified_data: { google_id: true },
391
- });
392
-
393
- const res = await fetch(
394
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
395
- {
396
- method: "POST",
397
- headers: { Authorization: "Bearer some-token" },
398
- },
399
- );
400
- expect(await res.json()).toEqual({ status: "OK" });
401
- const migratedUser =
402
- await getMigratedUserByRowndUserId("rownd-user-google");
403
- expect(migratedUser).toBeDefined();
404
- const user = migratedUser!.user;
405
- expect(user?.loginMethods.length).toBe(1);
406
- expect(user?.loginMethods[0].recipeId).toBe("thirdparty");
407
- expect(user?.loginMethods[0].thirdParty?.id).toBe("google");
408
- });
409
-
410
- it("error if the auth header is missing", async () => {
411
- const { server: s, port } = await setup(coreConnectionURI);
412
- server = s;
413
- testPORT = port;
414
- const res = await fetch(
415
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
416
- {
417
- method: "POST",
418
- },
419
- );
420
- const body = await res.json();
421
- expect(body.status).toBe("ERROR");
422
- expect(body.message).toBe(
423
- ROWND_PLUGIN_ERROR_MESSAGES.MISSING_AUTHORIZATION_HEADER,
424
- );
425
- });
426
-
427
- it("error if rownd token validation fails", async () => {
428
- const { server: s, port } = await setup(coreConnectionURI);
429
- server = s;
430
- testPORT = port;
431
- mockRowndClient.validateToken.mockRejectedValue(
432
- new Error("Invalid token API"),
433
- );
434
-
435
- const res = await fetch(
436
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
437
- {
438
- method: "POST",
439
- headers: { Authorization: "Bearer some-token" },
440
- },
441
- );
442
- const body = await res.json();
443
- expect(body.status).toBe("ERROR");
444
- expect(body.message).toBe("Migration failed");
445
- });
446
-
447
- it("error if rownd user info fetch fails", async () => {
448
- const telemetryClient: RowndTelemetryClient = {
449
- recordEvent: vi.fn(),
450
- };
451
- const { server: s, port } = await setup(coreConnectionURI, {
452
- telemetry: {
453
- provider: "custom",
454
- factory: () => telemetryClient,
455
- },
456
- });
457
- server = s;
458
- testPORT = port;
459
- mockRowndClient.validateToken.mockResolvedValue({
460
- user_id: "rownd-user-fetch-fail",
461
- });
462
- mockRowndClient.fetchUserInfo.mockRejectedValue(
463
- new Error("Fetch failed"),
464
- );
465
-
466
- const res = await fetch(
467
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
468
- {
469
- method: "POST",
470
- headers: { Authorization: "Bearer some-token" },
471
- },
472
- );
473
- const body = await res.json();
474
- expect(body.status).toBe("ERROR");
475
- expect(body.message).toBe("Migration failed");
476
- expect(telemetryClient.recordEvent).toHaveBeenCalledWith(
477
- expect.objectContaining({
478
- outcome: "error",
479
- rowndUserId: "rownd-user-fetch-fail",
480
- error: expect.objectContaining({
481
- message: "Fetch failed",
482
- }),
483
- }),
484
- );
485
- });
486
-
487
- it("telemetry failure does not affect response", async () => {
488
- const telemetryClient: RowndTelemetryClient = {
489
- recordEvent: vi.fn(async () => {
490
- throw new Error("Telemetry down");
491
- }),
492
- };
493
- const { server: s, port } = await setup(coreConnectionURI, {
494
- telemetry: {
495
- provider: "custom",
496
- factory: () => telemetryClient,
497
- },
498
- });
499
- server = s;
500
- testPORT = port;
501
-
502
- mockRowndClient.validateToken.mockResolvedValue({
503
- user_id: "rownd-user-telemetry-throw",
504
- });
505
- mockRowndClient.fetchUserInfo.mockResolvedValue({
506
- app_user_id: "rownd-user-telemetry-throw",
507
- data: {
508
- user_id: "rownd-user-telemetry-throw",
509
- email: "telemetry@example.com",
510
- },
511
- verified_data: { email: true },
512
- });
513
-
514
- const res = await fetch(
515
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
516
- {
517
- method: "POST",
518
- headers: { Authorization: "Bearer some-token" },
519
- },
520
- );
521
- expect(await res.json()).toEqual({ status: "OK" });
522
- expect(telemetryClient.recordEvent).toHaveBeenCalled();
523
- });
524
-
525
- it("prevent creation of duplicate users", async () => {
526
- const { server: s, port } = await setup(coreConnectionURI);
527
- server = s;
528
- testPORT = port;
529
- mockRowndClient.validateToken.mockResolvedValue({ user_id: "rownd-dup" });
530
- mockRowndClient.fetchUserInfo.mockResolvedValue({
531
- app_user_id: "rownd-dup",
532
- data: { user_id: "rownd-dup", email: "dup@example.com" },
533
- verified_data: { email: true },
534
- });
535
-
536
- await fetch(`http://localhost:${testPORT}/auth/plugin/rownd/migrate`, {
537
- method: "POST",
538
- headers: { Authorization: "Bearer some-token" },
539
- });
540
-
541
- const res = await fetch(
542
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
543
- {
544
- method: "POST",
545
- headers: { Authorization: "Bearer some-token" },
546
- },
547
- );
548
- expect(await res.json()).toEqual({ status: "OK" });
549
-
550
- const migratedUser = await getMigratedUserByRowndUserId("rownd-dup");
551
- expect(migratedUser).toBeDefined();
552
- const user = migratedUser!.user;
553
- expect(user).toBeDefined();
554
- });
555
-
556
- it("error if user not found in rownd", async () => {
557
- const { server: s, port } = await setup(coreConnectionURI);
558
- server = s;
559
- testPORT = port;
560
- mockRowndClient.validateToken.mockResolvedValue({
561
- user_id: "rownd-missing",
562
- });
563
- mockRowndClient.fetchUserInfo.mockResolvedValue(undefined);
564
-
565
- const res = await fetch(
566
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
567
- {
568
- method: "POST",
569
- headers: { Authorization: "Bearer some-token" },
570
- },
571
- );
572
- const body = await res.json();
573
- expect(body.status).toBe("ERROR");
574
- expect(body.message).toBe(
575
- ROWND_PLUGIN_ERROR_MESSAGES.ROWND_USER_NOT_FOUND,
576
- );
577
- });
578
- });
579
-
580
- describe("session migration", () => {
581
- it("migrate session successfully", async () => {
582
- const { server: s, port } = await setup(coreConnectionURI);
583
- server = s;
584
- testPORT = port;
585
- mockRowndClient.validateToken.mockResolvedValue({
586
- user_id: "rownd-session-1",
587
- });
588
- mockRowndClient.fetchUserInfo.mockResolvedValue({
589
- app_user_id: "rownd-session-1",
590
- data: { user_id: "rownd-session-1", email: "session@example.com" },
591
- verified_data: { email: true },
592
- });
593
-
594
- const res = await fetch(
595
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
596
- {
597
- method: "POST",
598
- headers: {
599
- Authorization: "Bearer some-token",
600
- rid: "session",
601
- "fdi-version": "1.18",
602
- },
603
- },
604
- );
605
- const body = await res.json();
606
- expect(res.status).toBe(200);
607
- expect(body).toEqual({ status: "OK" });
608
- expect(res.headers.get("front-token")).toBeTruthy();
609
- expect(
610
- res.headers.get("st-access-token") || res.headers.get("set-cookie"),
611
- ).toBeTruthy();
612
- });
613
-
614
- it("create user and then migrate their session", async () => {
615
- const { server: s, port } = await setup(coreConnectionURI);
616
- server = s;
617
- testPORT = port;
618
- mockRowndClient.validateToken.mockResolvedValue({
619
- user_id: "rownd-session-2",
620
- });
621
- mockRowndClient.fetchUserInfo.mockResolvedValue({
622
- app_user_id: "rownd-session-2",
623
- data: { user_id: "rownd-session-2", email: "session2@example.com" },
624
- verified_data: { email: true },
625
- });
626
-
627
- const res = await fetch(
628
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
629
- {
630
- method: "POST",
631
- headers: {
632
- Authorization: "Bearer some-token",
633
- rid: "session",
634
- "fdi-version": "1.18",
635
- },
636
- },
637
- );
638
- expect(await res.json()).toEqual({ status: "OK" });
639
- });
640
-
641
- it("error if the auth header is missing", async () => {
642
- const { server: s, port } = await setup(coreConnectionURI);
643
- server = s;
644
- testPORT = port;
645
- const res = await fetch(
646
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
647
- {
648
- method: "POST",
649
- },
650
- );
651
- const body = await res.json();
652
- expect(body.status).toBe("ERROR");
653
- });
654
-
655
- it("error if rownd token validation fails", async () => {
656
- const { server: s, port } = await setup(coreConnectionURI);
657
- server = s;
658
- testPORT = port;
659
- mockRowndClient.validateToken.mockRejectedValue(
660
- new Error("Invalid token"),
661
- );
662
- const res = await fetch(
663
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
664
- {
665
- method: "POST",
666
- headers: { Authorization: "Bearer some-token" },
667
- },
668
- );
669
- expect((await res.json()).status).toBe("ERROR");
670
- });
671
-
672
- it("error if rownd user info fetch fails", async () => {
673
- const { server: s, port } = await setup(coreConnectionURI);
674
- server = s;
675
- testPORT = port;
676
- mockRowndClient.validateToken.mockResolvedValue({
677
- user_id: "rownd-session-3",
678
- });
679
- mockRowndClient.fetchUserInfo.mockRejectedValue(new Error("Failed"));
680
- const res = await fetch(
681
- `http://localhost:${testPORT}/auth/plugin/rownd/migrate`,
682
- {
683
- method: "POST",
684
- headers: { Authorization: "Bearer some-token" },
685
- },
686
- );
687
- expect((await res.json()).status).toBe("ERROR");
688
- });
689
- });
690
- });
691
-
692
- function resetST() {
693
- ProcessState.getInstance().reset();
694
- SessionRaw.reset();
695
- UserMetadataRaw.reset();
696
- UserRolesRaw.reset();
697
- AccountLinkingRaw.reset();
698
- EmailPasswordRaw.reset();
699
- PasswordlessRaw.reset();
700
- ThirdPartyRaw.reset();
701
- MultitenancyRaw.reset();
702
- SuperTokensRaw.reset();
703
- Querier.reset();
704
- }
705
-
706
- async function getMigratedUserByRowndUserId(rowndUserId: string) {
707
- const user = await SuperTokens.getUser(rowndUserId);
708
- if (!user) {
709
- return undefined;
710
- }
711
-
712
- const metadata = await getUserMetadata(rowndUserId);
713
-
714
- return {
715
- user,
716
- metadata,
717
- };
718
- }
719
-
720
- async function setup(
721
- coreConnectionURI: string,
722
- config?: Partial<RowndPluginConfig>,
723
- ): Promise<{ server: Server; port: number }> {
724
- const app = express();
725
-
726
- return new Promise((resolve) => {
727
- const s = app.listen(0, () => {
728
- const address = s.address() as any;
729
- const port = address.port;
730
-
731
- SuperTokens.init({
732
- supertokens: {
733
- connectionURI: coreConnectionURI,
734
- },
735
- appInfo: {
736
- appName: "Test App",
737
- apiDomain: `http://localhost:${port}`,
738
- websiteDomain: `http://localhost:${port + 1}`,
739
- },
740
- recipeList: [
741
- Session.init(),
742
- AccountLinking.init({
743
- shouldDoAutomaticAccountLinking: async () => ({
744
- shouldAutomaticallyLink: true,
745
- shouldRequireVerification: false,
746
- }),
747
- }),
748
- UserMetadata.init(),
749
- Passwordless.init({
750
- contactMethod: "EMAIL",
751
- flowType: "MAGIC_LINK",
752
- }),
753
- ThirdParty.init({
754
- signInAndUpFeature: {
755
- providers: [
756
- {
757
- config: {
758
- thirdPartyId: "google",
759
- clients: [{ clientId: "test", clientSecret: "test" }],
760
- },
761
- },
762
- {
763
- config: {
764
- thirdPartyId: "apple",
765
- clients: [{ clientId: "test", clientSecret: "test" }],
766
- },
767
- },
768
- ],
769
- },
770
- }),
771
- ],
772
- experimental: {
773
- plugins: [
774
- init({
775
- rowndAppKey: "test-key",
776
- rowndAppSecret: "test-secret",
777
- enableDebugLogs: true,
778
- ...config,
779
- } as RowndPluginConfig),
780
- ],
781
- },
782
- });
783
-
784
- app.use(middleware());
785
- app.use(errorHandler());
786
-
787
- resolve({ server: s, port });
788
- });
789
- });
790
- }