@supertokens-plugins/rownd-nodejs 0.2.0 → 0.3.0-beta.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/index.js ADDED
@@ -0,0 +1,2752 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // ../../node_modules/supertokens-js-override/lib/build/getProxyObject.js
34
+ var require_getProxyObject = __commonJS({
35
+ "../../node_modules/supertokens-js-override/lib/build/getProxyObject.js"(exports2) {
36
+ "use strict";
37
+ var __assign = exports2 && exports2.__assign || function() {
38
+ __assign = Object.assign || function(t) {
39
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
40
+ s = arguments[i];
41
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
42
+ t[p] = s[p];
43
+ }
44
+ return t;
45
+ };
46
+ return __assign.apply(this, arguments);
47
+ };
48
+ Object.defineProperty(exports2, "__esModule", { value: true });
49
+ exports2.getProxyObject = void 0;
50
+ function getProxyObject(orig) {
51
+ var ret = __assign(__assign({}, orig), { _call: function(_, __) {
52
+ throw new Error("This function should only be called through the recipe object");
53
+ } });
54
+ var keys = Object.keys(ret);
55
+ var _loop_1 = function(k2) {
56
+ if (k2 !== "_call") {
57
+ ret[k2] = function() {
58
+ var args = [];
59
+ for (var _i2 = 0; _i2 < arguments.length; _i2++) {
60
+ args[_i2] = arguments[_i2];
61
+ }
62
+ return this._call(k2, args);
63
+ };
64
+ }
65
+ };
66
+ for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
67
+ var k = keys_1[_i];
68
+ _loop_1(k);
69
+ }
70
+ return ret;
71
+ }
72
+ exports2.getProxyObject = getProxyObject;
73
+ }
74
+ });
75
+
76
+ // ../../node_modules/supertokens-js-override/lib/build/index.js
77
+ var require_build = __commonJS({
78
+ "../../node_modules/supertokens-js-override/lib/build/index.js"(exports2) {
79
+ "use strict";
80
+ Object.defineProperty(exports2, "__esModule", { value: true });
81
+ exports2.OverrideableBuilder = void 0;
82
+ var getProxyObject_1 = require_getProxyObject();
83
+ var OverrideableBuilder2 = (
84
+ /** @class */
85
+ (function() {
86
+ function OverrideableBuilder3(originalImplementation) {
87
+ this.layers = [originalImplementation];
88
+ this.proxies = [];
89
+ }
90
+ OverrideableBuilder3.prototype.override = function(overrideFunc) {
91
+ var proxy = (0, getProxyObject_1.getProxyObject)(this.layers[0]);
92
+ var layer = overrideFunc(proxy, this);
93
+ for (var _i = 0, _a = Object.keys(this.layers[0]); _i < _a.length; _i++) {
94
+ var key = _a[_i];
95
+ if (layer[key] === proxy[key] || key === "_call") {
96
+ delete layer[key];
97
+ } else if (layer[key] === void 0) {
98
+ layer[key] = null;
99
+ }
100
+ }
101
+ this.layers.push(layer);
102
+ this.proxies.push(proxy);
103
+ return this;
104
+ };
105
+ OverrideableBuilder3.prototype.build = function() {
106
+ var _this = this;
107
+ if (this.result) {
108
+ return this.result;
109
+ }
110
+ this.result = {};
111
+ for (var _i = 0, _a = this.layers; _i < _a.length; _i++) {
112
+ var layer = _a[_i];
113
+ for (var _b = 0, _c = Object.keys(layer); _b < _c.length; _b++) {
114
+ var key = _c[_b];
115
+ var override = layer[key];
116
+ if (override !== void 0) {
117
+ if (override === null) {
118
+ this.result[key] = void 0;
119
+ } else if (typeof override === "function") {
120
+ this.result[key] = override.bind(this.result);
121
+ } else {
122
+ this.result[key] = override;
123
+ }
124
+ }
125
+ }
126
+ }
127
+ var _loop_1 = function(proxyInd2) {
128
+ var proxy = this_1.proxies[proxyInd2];
129
+ proxy._call = function(fname, args) {
130
+ for (var i = proxyInd2; i >= 0; --i) {
131
+ var func = _this.layers[i][fname];
132
+ if (func !== void 0 && func !== null) {
133
+ return func.bind(_this.result).apply(void 0, args);
134
+ }
135
+ }
136
+ };
137
+ };
138
+ var this_1 = this;
139
+ for (var proxyInd = 0; proxyInd < this.proxies.length; ++proxyInd) {
140
+ _loop_1(proxyInd);
141
+ }
142
+ return this.result;
143
+ };
144
+ return OverrideableBuilder3;
145
+ })()
146
+ );
147
+ exports2.OverrideableBuilder = OverrideableBuilder2;
148
+ exports2.default = OverrideableBuilder2;
149
+ }
150
+ });
151
+
152
+ // ../../node_modules/has-flag/index.js
153
+ var require_has_flag = __commonJS({
154
+ "../../node_modules/has-flag/index.js"(exports2, module2) {
155
+ "use strict";
156
+ module2.exports = (flag, argv = process.argv) => {
157
+ const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
158
+ const position = argv.indexOf(prefix + flag);
159
+ const terminatorPosition = argv.indexOf("--");
160
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
161
+ };
162
+ }
163
+ });
164
+
165
+ // ../../node_modules/supports-color/index.js
166
+ var require_supports_color = __commonJS({
167
+ "../../node_modules/supports-color/index.js"(exports2, module2) {
168
+ "use strict";
169
+ var os = require("os");
170
+ var tty = require("tty");
171
+ var hasFlag = require_has_flag();
172
+ var { env } = process;
173
+ var forceColor;
174
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
175
+ forceColor = 0;
176
+ } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
177
+ forceColor = 1;
178
+ }
179
+ if ("FORCE_COLOR" in env) {
180
+ if (env.FORCE_COLOR === "true") {
181
+ forceColor = 1;
182
+ } else if (env.FORCE_COLOR === "false") {
183
+ forceColor = 0;
184
+ } else {
185
+ forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
186
+ }
187
+ }
188
+ function translateLevel(level) {
189
+ if (level === 0) {
190
+ return false;
191
+ }
192
+ return {
193
+ level,
194
+ hasBasic: true,
195
+ has256: level >= 2,
196
+ has16m: level >= 3
197
+ };
198
+ }
199
+ function supportsColor(haveStream, streamIsTTY) {
200
+ if (forceColor === 0) {
201
+ return 0;
202
+ }
203
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
204
+ return 3;
205
+ }
206
+ if (hasFlag("color=256")) {
207
+ return 2;
208
+ }
209
+ if (haveStream && !streamIsTTY && forceColor === void 0) {
210
+ return 0;
211
+ }
212
+ const min = forceColor || 0;
213
+ if (env.TERM === "dumb") {
214
+ return min;
215
+ }
216
+ if (process.platform === "win32") {
217
+ const osRelease = os.release().split(".");
218
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
219
+ return Number(osRelease[2]) >= 14931 ? 3 : 2;
220
+ }
221
+ return 1;
222
+ }
223
+ if ("CI" in env) {
224
+ if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
225
+ return 1;
226
+ }
227
+ return min;
228
+ }
229
+ if ("TEAMCITY_VERSION" in env) {
230
+ return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
231
+ }
232
+ if (env.COLORTERM === "truecolor") {
233
+ return 3;
234
+ }
235
+ if ("TERM_PROGRAM" in env) {
236
+ const version = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
237
+ switch (env.TERM_PROGRAM) {
238
+ case "iTerm.app":
239
+ return version >= 3 ? 3 : 2;
240
+ case "Apple_Terminal":
241
+ return 2;
242
+ }
243
+ }
244
+ if (/-256(color)?$/i.test(env.TERM)) {
245
+ return 2;
246
+ }
247
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
248
+ return 1;
249
+ }
250
+ if ("COLORTERM" in env) {
251
+ return 1;
252
+ }
253
+ return min;
254
+ }
255
+ function getSupportLevel(stream) {
256
+ const level = supportsColor(stream, stream && stream.isTTY);
257
+ return translateLevel(level);
258
+ }
259
+ module2.exports = {
260
+ supportsColor: getSupportLevel,
261
+ stdout: translateLevel(supportsColor(true, tty.isatty(1))),
262
+ stderr: translateLevel(supportsColor(true, tty.isatty(2)))
263
+ };
264
+ }
265
+ });
266
+
267
+ // src/index.ts
268
+ var index_exports = {};
269
+ __export(index_exports, {
270
+ ANONYMOUS_AUTH_METHOD_ID: () => ANONYMOUS_AUTH_METHOD_ID,
271
+ DEFAULT_ROWND_SCHEMA: () => DEFAULT_ROWND_SCHEMA,
272
+ GUEST_AUTH_METHOD_ID: () => GUEST_AUTH_METHOD_ID,
273
+ HANDLE_BASE_PATH: () => HANDLE_BASE_PATH,
274
+ PLUGIN_ID: () => PLUGIN_ID,
275
+ PLUGIN_SDK_VERSION: () => PLUGIN_SDK_VERSION,
276
+ PUBLIC_TENANT_ID: () => PUBLIC_TENANT_ID,
277
+ ROWND_JWT_CLAIMS: () => ROWND_JWT_CLAIMS,
278
+ ROWND_PLUGIN_ERROR_MESSAGES: () => ROWND_PLUGIN_ERROR_MESSAGES,
279
+ RowndPluginError: () => RowndPluginError,
280
+ default: () => index_default,
281
+ getRowndClient: () => getRowndClient,
282
+ init: () => init,
283
+ setRowndClient: () => setRowndClient
284
+ });
285
+ module.exports = __toCommonJS(index_exports);
286
+
287
+ // ../../shared/js/src/createPluginInit.ts
288
+ var import_supertokens_js_override = __toESM(require_build());
289
+ var createPluginInitFunction = (init2, getImplementation, getNormalisedConfig = (config2) => config2) => {
290
+ const getNormalizedImplementation = typeof getImplementation === "function" ? getImplementation : (_config) => getImplementation || {};
291
+ return (inputConfig) => {
292
+ const config2 = getNormalisedConfig(inputConfig || {});
293
+ const baseImplementation = getNormalizedImplementation(config2);
294
+ const overrideBuilder = new import_supertokens_js_override.OverrideableBuilder(baseImplementation);
295
+ if (inputConfig?.override) {
296
+ overrideBuilder.override(inputConfig.override);
297
+ }
298
+ const actualImplementation = overrideBuilder.build();
299
+ return init2(config2, actualImplementation);
300
+ };
301
+ };
302
+
303
+ // ../../shared/nodejs/src/pluginUserMetadata.ts
304
+ var import_usermetadata = __toESM(require("supertokens-node/recipe/usermetadata"));
305
+
306
+ // ../../shared/nodejs/src/withRequestHandler.ts
307
+ var withRequestHandler = (fn) => {
308
+ return async (req, res, session, userContext) => {
309
+ const result = await fn(req, res, session, userContext);
310
+ if (result.status === "OK") {
311
+ res.setStatusCode(200);
312
+ } else {
313
+ res.setStatusCode(Number(result.code) || 400);
314
+ }
315
+ res.sendJSONResponse(result);
316
+ return null;
317
+ };
318
+ };
319
+
320
+ // ../../shared/nodejs/src/log/logger.ts
321
+ var import_util = __toESM(require("util"));
322
+
323
+ // ../../shared/nodejs/src/log/common.ts
324
+ function setup(env) {
325
+ createDebug.debug = createDebug;
326
+ createDebug.default = createDebug;
327
+ createDebug.coerce = coerce;
328
+ createDebug.disable = disable;
329
+ createDebug.enable = enable;
330
+ createDebug.enabled = enabled;
331
+ createDebug.humanize = env.humanize;
332
+ createDebug.destroy = destroy;
333
+ Object.keys(env).forEach((key) => {
334
+ createDebug[key] = env[key];
335
+ });
336
+ createDebug.names = [];
337
+ createDebug.skips = [];
338
+ createDebug.formatters = {};
339
+ function selectColor(namespace) {
340
+ let hash = 0;
341
+ for (let i = 0; i < namespace.length; i++) {
342
+ hash = (hash << 5) - hash + namespace.charCodeAt(i);
343
+ hash |= 0;
344
+ }
345
+ return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
346
+ }
347
+ createDebug.selectColor = selectColor;
348
+ function createDebug(namespace) {
349
+ let prevTime;
350
+ let enableOverride = null;
351
+ let namespacesCache;
352
+ let enabledCache;
353
+ function debug(...args) {
354
+ if (!debug.enabled) {
355
+ return;
356
+ }
357
+ const self = debug;
358
+ const curr = Number(/* @__PURE__ */ new Date());
359
+ const ms = curr - (prevTime || curr);
360
+ self.diff = ms;
361
+ self.prev = prevTime;
362
+ self.curr = curr;
363
+ prevTime = curr;
364
+ args[0] = createDebug.coerce(args[0]);
365
+ if (typeof args[0] !== "string") {
366
+ args.unshift("%O");
367
+ }
368
+ let index = 0;
369
+ args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
370
+ if (match === "%%") {
371
+ return "%";
372
+ }
373
+ index++;
374
+ const formatter = createDebug.formatters[format];
375
+ if (typeof formatter === "function") {
376
+ const val = args[index];
377
+ match = formatter.call(self, val);
378
+ args.splice(index, 1);
379
+ index--;
380
+ }
381
+ return match;
382
+ });
383
+ createDebug.formatArgs.call(self, args);
384
+ const logFn = self.log || createDebug.log;
385
+ logFn.apply(self, args);
386
+ }
387
+ debug.namespace = namespace;
388
+ debug.useColors = createDebug.useColors();
389
+ debug.color = createDebug.selectColor(namespace);
390
+ debug.extend = extend;
391
+ debug.destroy = createDebug.destroy;
392
+ Object.defineProperty(debug, "enabled", {
393
+ enumerable: true,
394
+ configurable: false,
395
+ get: () => {
396
+ if (enableOverride !== null) {
397
+ return enableOverride;
398
+ }
399
+ if (namespacesCache !== createDebug.namespaces) {
400
+ namespacesCache = createDebug.namespaces;
401
+ enabledCache = createDebug.enabled(namespace);
402
+ }
403
+ return enabledCache;
404
+ },
405
+ set: (v) => {
406
+ enableOverride = v;
407
+ }
408
+ });
409
+ if (typeof createDebug.init === "function") {
410
+ createDebug.init(debug);
411
+ }
412
+ return debug;
413
+ }
414
+ function extend(namespace, delimiter) {
415
+ const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
416
+ newDebug.log = this.log;
417
+ return newDebug;
418
+ }
419
+ function enable(namespaces) {
420
+ createDebug.save(namespaces);
421
+ createDebug.namespaces = namespaces;
422
+ createDebug.names = [];
423
+ createDebug.skips = [];
424
+ const split = (typeof namespaces === "string" ? namespaces : "").trim().replace(/\s+/g, ",").split(",").filter(Boolean);
425
+ for (const ns of split) {
426
+ if (ns[0] === "-") {
427
+ createDebug.skips.push(ns.slice(1));
428
+ } else {
429
+ createDebug.names.push(ns);
430
+ }
431
+ }
432
+ }
433
+ function matchesTemplate(search, template) {
434
+ let searchIndex = 0;
435
+ let templateIndex = 0;
436
+ let starIndex = -1;
437
+ let matchIndex = 0;
438
+ while (searchIndex < search.length) {
439
+ if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) {
440
+ if (template[templateIndex] === "*") {
441
+ starIndex = templateIndex;
442
+ matchIndex = searchIndex;
443
+ templateIndex++;
444
+ } else {
445
+ searchIndex++;
446
+ templateIndex++;
447
+ }
448
+ } else if (starIndex !== -1) {
449
+ templateIndex = starIndex + 1;
450
+ matchIndex++;
451
+ searchIndex = matchIndex;
452
+ } else {
453
+ return false;
454
+ }
455
+ }
456
+ while (templateIndex < template.length && template[templateIndex] === "*") {
457
+ templateIndex++;
458
+ }
459
+ return templateIndex === template.length;
460
+ }
461
+ function disable() {
462
+ const namespaces = [...createDebug.names, ...createDebug.skips.map((namespace) => "-" + namespace)].join(",");
463
+ createDebug.enable("");
464
+ return namespaces;
465
+ }
466
+ function enabled(name) {
467
+ for (const skip of createDebug.skips) {
468
+ if (matchesTemplate(name, skip)) {
469
+ return false;
470
+ }
471
+ }
472
+ for (const ns of createDebug.names) {
473
+ if (matchesTemplate(name, ns)) {
474
+ return true;
475
+ }
476
+ }
477
+ return false;
478
+ }
479
+ function coerce(val) {
480
+ if (val instanceof Error) {
481
+ return val.stack || val.message;
482
+ }
483
+ return val;
484
+ }
485
+ function destroy() {
486
+ console.warn(
487
+ "Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."
488
+ );
489
+ }
490
+ createDebug.enable(createDebug.load());
491
+ return createDebug;
492
+ }
493
+ var common_default = setup;
494
+
495
+ // ../../shared/nodejs/src/log/logger.ts
496
+ var BASIC_COLORS = [6, 2, 3, 4, 5, 1];
497
+ var EXTENDED_COLORS = [
498
+ 20,
499
+ 21,
500
+ 26,
501
+ 27,
502
+ 32,
503
+ 33,
504
+ 38,
505
+ 39,
506
+ 40,
507
+ 41,
508
+ 42,
509
+ 43,
510
+ 44,
511
+ 45,
512
+ 56,
513
+ 57,
514
+ 62,
515
+ 63,
516
+ 68,
517
+ 69,
518
+ 74,
519
+ 75,
520
+ 76,
521
+ 77,
522
+ 78,
523
+ 79,
524
+ 80,
525
+ 81,
526
+ 92,
527
+ 93,
528
+ 98,
529
+ 99,
530
+ 112,
531
+ 113,
532
+ 128,
533
+ 129,
534
+ 134,
535
+ 135,
536
+ 148,
537
+ 149,
538
+ 160,
539
+ 161,
540
+ 162,
541
+ 163,
542
+ 164,
543
+ 165,
544
+ 166,
545
+ 167,
546
+ 168,
547
+ 169,
548
+ 170,
549
+ 171,
550
+ 172,
551
+ 173,
552
+ 178,
553
+ 179,
554
+ 184,
555
+ 185,
556
+ 196,
557
+ 197,
558
+ 198,
559
+ 199,
560
+ 200,
561
+ 201,
562
+ 202,
563
+ 203,
564
+ 204,
565
+ 205,
566
+ 206,
567
+ 207,
568
+ 208,
569
+ 209,
570
+ 214,
571
+ 215,
572
+ 220,
573
+ 221
574
+ ];
575
+ function supportsExtendedColors() {
576
+ try {
577
+ const supportsColor = require_supports_color();
578
+ return supportsColor && (supportsColor.stderr || supportsColor).level >= 2;
579
+ } catch {
580
+ return false;
581
+ }
582
+ }
583
+ function shouldUseColors() {
584
+ return false;
585
+ }
586
+ function formatArgs(args) {
587
+ const { namespace, useColors, color } = this;
588
+ if (useColors) {
589
+ const colorCode = color < 8 ? `3${color}` : `38;5;${color}`;
590
+ const prefix = `\x1B[${colorCode};1m${namespace}\x1B[0m`;
591
+ args[0] = `${prefix} ${args[0]}`.split("\n").join(`
592
+ ${prefix} `);
593
+ args.push(`\x1B[${colorCode}m+${humanizeTime(this.diff)}\x1B[0m`);
594
+ } else {
595
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
596
+ args[0] = `${timestamp} ${namespace} ${args[0]}`;
597
+ }
598
+ }
599
+ function writeOutput(...args) {
600
+ process.stderr.write(import_util.default.format(...args) + "\n");
601
+ }
602
+ function saveConfig(namespaces) {
603
+ if (namespaces) {
604
+ process.env.DEBUG = namespaces;
605
+ } else {
606
+ delete process.env.DEBUG;
607
+ }
608
+ }
609
+ function loadConfig() {
610
+ return process.env.DEBUG;
611
+ }
612
+ function humanizeTime(milliseconds) {
613
+ if (milliseconds >= 1e3) {
614
+ const seconds = Math.round(milliseconds / 1e3);
615
+ return `${seconds}s`;
616
+ }
617
+ return `${milliseconds}ms`;
618
+ }
619
+ function createLoggerConfig() {
620
+ const colors = supportsExtendedColors() ? EXTENDED_COLORS : BASIC_COLORS;
621
+ return {
622
+ colors,
623
+ useColors: shouldUseColors,
624
+ formatArgs,
625
+ log: writeOutput,
626
+ save: saveConfig,
627
+ load: loadConfig,
628
+ humanize: humanizeTime
629
+ };
630
+ }
631
+ var config = createLoggerConfig();
632
+ var logger = common_default(config);
633
+ if (logger.formatters) {
634
+ logger.formatters.o = function(value) {
635
+ return import_util.default.inspect(value, { colors: this.useColors, compact: true }).split("\n").map((line) => line.trim()).join(" ");
636
+ };
637
+ logger.formatters.O = function(value) {
638
+ return import_util.default.inspect(value, { colors: this.useColors, compact: false });
639
+ };
640
+ }
641
+ var logger_default = logger;
642
+
643
+ // ../../shared/nodejs/src/log/index.ts
644
+ var log_default = logger_default;
645
+
646
+ // ../../shared/nodejs/src/logger.ts
647
+ var getFileLocation = () => {
648
+ let errorObject = new Error();
649
+ if (errorObject.stack === void 0) {
650
+ return "N/A";
651
+ }
652
+ let errorStack = errorObject.stack.split("\n");
653
+ for (let i = 1; i < errorStack.length; i++) {
654
+ if (!errorStack[i]?.includes("logger.js")) {
655
+ return errorStack[i]?.match(/(?<=\().+?(?=\))/g);
656
+ }
657
+ }
658
+ return "N/A";
659
+ };
660
+ var buildLogger = (pluginId, version, { fileLocation = true } = {}) => {
661
+ const namespace = `com.supertokens.plugin.${pluginId}`;
662
+ function logDebugMessage2(message) {
663
+ if (log_default.enabled(namespace)) {
664
+ log_default(namespace)(
665
+ `{t: "${(/* @__PURE__ */ new Date()).toISOString()}", message: "${message}", file: "${fileLocation ? getFileLocation() : "N/A"}" version: "${version}"}`
666
+ );
667
+ console.log();
668
+ }
669
+ }
670
+ function enableDebugLogs2() {
671
+ log_default.enable(namespace);
672
+ }
673
+ return {
674
+ logDebugMessage: logDebugMessage2,
675
+ enableDebugLogs: enableDebugLogs2
676
+ };
677
+ };
678
+
679
+ // src/plugin.ts
680
+ var import_node = require("@rownd/node");
681
+ var import_supertokens_node2 = __toESM(require("supertokens-node"));
682
+
683
+ // src/constants.ts
684
+ var PLUGIN_ID = "supertokens-plugin-rownd";
685
+ var PLUGIN_SDK_VERSION = ["23.0.0", "23.0.1", ">=23.0.1"];
686
+ var HANDLE_BASE_PATH = "/plugin/rownd";
687
+ var PUBLIC_TENANT_ID = "public";
688
+ var GUEST_AUTH_METHOD_ID = "guest";
689
+ var ANONYMOUS_AUTH_METHOD_ID = "anonymous";
690
+ var ROWND_JWT_CLAIMS = {
691
+ AppUserId: "https://auth.rownd.io/app_user_id",
692
+ IsVerifiedUser: "https://auth.rownd.io/is_verified_user",
693
+ IsAnonymous: "https://auth.rownd.io/is_anonymous",
694
+ IssuedOffline: "https://auth.rownd.io/issued_offline",
695
+ JwtType: "https://auth.rownd.io/jwt_type",
696
+ PlatformJwt: "https://auth.rownd.io/platform_jwt",
697
+ AuthLevel: "https://auth.rownd.io/auth_level"
698
+ };
699
+ var DEFAULT_ROWND_SCHEMA = {
700
+ zip_code: {
701
+ display_name: "Zip code",
702
+ type: "string",
703
+ user_visible: true
704
+ },
705
+ last_name: {
706
+ display_name: "Last name",
707
+ type: "string",
708
+ user_visible: true
709
+ },
710
+ nick_name: {
711
+ display_name: "Nick name",
712
+ type: "string",
713
+ user_visible: true
714
+ },
715
+ first_name: {
716
+ display_name: "First name",
717
+ type: "string",
718
+ user_visible: true
719
+ }
720
+ };
721
+
722
+ // src/logger.ts
723
+ var { logDebugMessage, enableDebugLogs } = buildLogger(
724
+ PLUGIN_ID,
725
+ PLUGIN_SDK_VERSION
726
+ );
727
+
728
+ // src/telemetry/axiomTelemetryClient.ts
729
+ var DEFAULT_AXIOM_URL = "https://api.axiom.co/v1/datasets";
730
+ var AxiomTelemetryClient = class {
731
+ constructor(token, dataset, endpoint) {
732
+ this.token = token;
733
+ this.dataset = dataset;
734
+ const baseUrl = (endpoint ?? DEFAULT_AXIOM_URL).replace(/\/$/, "");
735
+ this.url = `${baseUrl}/${dataset}/ingest`;
736
+ }
737
+ token;
738
+ dataset;
739
+ url;
740
+ async recordEvent(event) {
741
+ await fetch(this.url, {
742
+ method: "POST",
743
+ headers: {
744
+ Authorization: `Bearer ${this.token}`,
745
+ "Content-Type": "application/json"
746
+ },
747
+ body: JSON.stringify([
748
+ {
749
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
750
+ plugin: PLUGIN_ID,
751
+ ...event
752
+ }
753
+ ])
754
+ });
755
+ }
756
+ };
757
+
758
+ // src/telemetry/openTelemetryClient.ts
759
+ var import_api = require("@opentelemetry/api");
760
+ var OpenTelemetryClient = class {
761
+ recordEvent(event) {
762
+ const tracer = import_api.trace.getTracer("supertokens-plugin-rownd", "0.1.0");
763
+ const span = tracer.startSpan("rownd.migrate");
764
+ span.setAttributes({
765
+ "rownd.outcome": event.outcome,
766
+ "rownd.duration_ms": event.durationMs,
767
+ "rownd.tenant_id": event.tenantId ?? "",
768
+ "rownd.rownd_user_id": event.rowndUserId ?? "",
769
+ "rownd.supertokens_user_id": event.superTokensUserId ?? ""
770
+ });
771
+ if (event.outcome === "error") {
772
+ const err = new Error(event.error.message);
773
+ if (event.error.name) {
774
+ err.name = event.error.name;
775
+ }
776
+ span.recordException(err);
777
+ span.setStatus({
778
+ code: import_api.SpanStatusCode.ERROR,
779
+ message: event.error.message
780
+ });
781
+ } else {
782
+ span.setStatus({ code: import_api.SpanStatusCode.OK });
783
+ }
784
+ span.end();
785
+ }
786
+ };
787
+
788
+ // src/telemetry/createTelemetryClient.ts
789
+ function createClient(telemetryConfig) {
790
+ let client;
791
+ if (telemetryConfig?.provider === "opentelemetry") {
792
+ client = new OpenTelemetryClient();
793
+ } else if (telemetryConfig?.provider === "axiom") {
794
+ client = new AxiomTelemetryClient(
795
+ telemetryConfig.token,
796
+ telemetryConfig.dataset,
797
+ telemetryConfig.url
798
+ );
799
+ } else if (telemetryConfig?.provider === "custom") {
800
+ client = telemetryConfig.factory();
801
+ }
802
+ return {
803
+ recordSuccess: (event) => {
804
+ if (!client) {
805
+ return;
806
+ }
807
+ safeRecordEvent(client, event, "success");
808
+ },
809
+ recordError: (input) => {
810
+ if (!client) {
811
+ return;
812
+ }
813
+ const event = {
814
+ outcome: "error",
815
+ durationMs: Date.now() - input.startedAt,
816
+ tenantId: input.tenantId,
817
+ rowndUserId: input.rowndUserId,
818
+ superTokensUserId: input.superTokensUserId,
819
+ error: {
820
+ message: input.error instanceof Error ? input.error.message : "Unknown error",
821
+ name: input.error instanceof Error ? input.error.name : void 0
822
+ }
823
+ };
824
+ safeRecordEvent(client, event, "error");
825
+ }
826
+ };
827
+ }
828
+ function safeRecordEvent(client, event, outcome) {
829
+ try {
830
+ Promise.resolve(client.recordEvent(event)).catch((error) => {
831
+ logDebugMessage(
832
+ `Failed to record telemetry ${outcome} event. Error: ${error instanceof Error ? error.message : "Unknown error"}`
833
+ );
834
+ });
835
+ } catch (error) {
836
+ logDebugMessage(
837
+ `Failed to record telemetry ${outcome} event. Error: ${error instanceof Error ? error.message : "Unknown error"}`
838
+ );
839
+ }
840
+ }
841
+
842
+ // src/pluginImplementation.ts
843
+ var import_crypto = require("crypto");
844
+ var import_supertokens_node = __toESM(require("supertokens-node"));
845
+ var import_accountlinking = __toESM(require("supertokens-node/recipe/accountlinking"));
846
+ var import_emailverification = __toESM(require("supertokens-node/recipe/emailverification"));
847
+ var import_passwordless = __toESM(require("supertokens-node/recipe/passwordless"));
848
+ var import_session = __toESM(require("supertokens-node/recipe/session"));
849
+ var import_claims = require("supertokens-node/recipe/session/claims");
850
+ var import_thirdparty = __toESM(require("supertokens-node/recipe/thirdparty"));
851
+ var import_usermetadata2 = __toESM(require("supertokens-node/recipe/usermetadata"));
852
+
853
+ // src/errors.ts
854
+ var ROWND_PLUGIN_ERROR_MESSAGES = {
855
+ MISSING_AUTHORIZATION_HEADER: "Missing authorization header",
856
+ INVALID_TOKEN: "Invalid token",
857
+ ROWND_USER_NOT_FOUND: "User not found in Rownd"
858
+ };
859
+ var RowndPluginError = class extends Error {
860
+ constructor(type) {
861
+ super(ROWND_PLUGIN_ERROR_MESSAGES[type]);
862
+ }
863
+ };
864
+
865
+ // src/pluginImplementation.ts
866
+ function rewriteLinkPath(inputUrl, targetPath, searchParams) {
867
+ try {
868
+ const url = new URL(inputUrl);
869
+ url.pathname = `/${targetPath.replace(/^\//, "")}`;
870
+ for (const [key, value] of Object.entries(searchParams ?? {})) {
871
+ url.searchParams.set(key, value);
872
+ }
873
+ return url.toString();
874
+ } catch {
875
+ const [path = inputUrl, query = ""] = inputUrl.replace(/auth\/verify[^?]*/, targetPath).split("?");
876
+ const params = new URLSearchParams(query);
877
+ for (const [key, value] of Object.entries(searchParams ?? {})) {
878
+ params.set(key, value);
879
+ }
880
+ const queryString = params.toString();
881
+ return queryString ? `${path}?${queryString}` : path;
882
+ }
883
+ }
884
+ var rowndClient;
885
+ var pluginConfig;
886
+ function setRowndClient(client) {
887
+ rowndClient = client;
888
+ }
889
+ function getRowndClient() {
890
+ if (!rowndClient) {
891
+ throw new Error("Rownd client not initialized");
892
+ }
893
+ return rowndClient;
894
+ }
895
+ function setPluginConfig(config2) {
896
+ pluginConfig = config2;
897
+ }
898
+ async function parseRequest(req) {
899
+ const authHeader = req.getHeaderValue("authorization");
900
+ if (!authHeader) {
901
+ throw new RowndPluginError("MISSING_AUTHORIZATION_HEADER");
902
+ }
903
+ const token = authHeader.replace(/^Bearer /i, "");
904
+ if (!token) {
905
+ throw new RowndPluginError("INVALID_TOKEN");
906
+ }
907
+ return {
908
+ token
909
+ };
910
+ }
911
+ function handleGetAppConfig(deps) {
912
+ return async (req) => {
913
+ const appVariantId = getRequestedAppVariantIdFromRequest(req);
914
+ const appConfig = buildAppConfig(
915
+ deps.pluginConfig,
916
+ deps.stConfig,
917
+ appVariantId
918
+ );
919
+ if (!appConfig) {
920
+ return {
921
+ status: "ERROR",
922
+ message: `Unknown Rownd app variant: ${appVariantId}`
923
+ };
924
+ }
925
+ return {
926
+ status: "OK",
927
+ ...appConfig
928
+ };
929
+ };
930
+ }
931
+ function handleGuestLogin(deps) {
932
+ return async (req, res, _session, userContext) => {
933
+ const startedAt = Date.now();
934
+ const guestId = `guest_${(0, import_crypto.randomUUID)()}`;
935
+ try {
936
+ const body = parseGuestBody(await getJsonBody(req));
937
+ const appVariantId = getRequestedAppVariantIdFromRequest(req);
938
+ assertRowndAppVariantIsConfigured(appVariantId);
939
+ const thirdPartyId = body.authLevel === ANONYMOUS_AUTH_METHOD_ID ? ANONYMOUS_AUTH_METHOD_ID : GUEST_AUTH_METHOD_ID;
940
+ const thirdPartyUserId = thirdPartyId === ANONYMOUS_AUTH_METHOD_ID ? `anon_${(0, import_crypto.randomUUID)()}` : guestId;
941
+ const response = await import_thirdparty.default.manuallyCreateOrUpdateUser(
942
+ PUBLIC_TENANT_ID,
943
+ thirdPartyId,
944
+ thirdPartyUserId,
945
+ `${thirdPartyUserId}@anonymous.local`,
946
+ false,
947
+ void 0,
948
+ userContext
949
+ );
950
+ if (response.status !== "OK") {
951
+ throw new Error(
952
+ `Guest user creation failed with status: ${response.status}`
953
+ );
954
+ }
955
+ await import_session.default.createNewSession(
956
+ req,
957
+ res,
958
+ PUBLIC_TENANT_ID,
959
+ response.recipeUserId,
960
+ {
961
+ ...buildRowndAudience({}, appVariantId),
962
+ auth_level: GUEST_AUTH_METHOD_ID,
963
+ is_anonymous: true,
964
+ app_user_id: response.user.id
965
+ },
966
+ {},
967
+ userContext
968
+ );
969
+ logDebugMessage(`Guest session created for user: ${response.user.id}`);
970
+ deps.telemetryClient.recordSuccess({
971
+ outcome: "success",
972
+ durationMs: Date.now() - startedAt,
973
+ tenantId: PUBLIC_TENANT_ID,
974
+ superTokensUserId: response.user.id
975
+ });
976
+ return {
977
+ status: "OK",
978
+ createdNewRecipeUser: response.createdNewRecipeUser
979
+ };
980
+ } catch (error) {
981
+ logDebugMessage(`Guest login failed. Error: ${getErrorMessage(error)}`);
982
+ deps.telemetryClient.recordError({
983
+ error,
984
+ startedAt,
985
+ tenantId: PUBLIC_TENANT_ID
986
+ });
987
+ return {
988
+ status: "ERROR",
989
+ message: "Guest login failed"
990
+ };
991
+ }
992
+ };
993
+ }
994
+ function handleMigrate(deps) {
995
+ return async (req, res, _session, userContext) => {
996
+ const startedAt = Date.now();
997
+ let tenantId = PUBLIC_TENANT_ID;
998
+ let rowndUserId;
999
+ let superTokensUserId;
1000
+ let user;
1001
+ let recipeUserId;
1002
+ try {
1003
+ if (!deps.stConfig.supertokens) {
1004
+ throw new Error("Supertokens config not found");
1005
+ }
1006
+ const parsed = await parseRequest(req);
1007
+ const appVariantId = getRequestedAppVariantIdFromRequest(req);
1008
+ assertRowndAppVariantIsConfigured(appVariantId);
1009
+ rowndUserId = await validateRowndToken(parsed.token);
1010
+ user = await import_supertokens_node.default.getUser(rowndUserId, userContext);
1011
+ if (!user) {
1012
+ const rowndUser = await fetchRowndUserInfo(rowndUserId);
1013
+ const stUserImport = mapRowndUserToSuperTokens(rowndUser);
1014
+ try {
1015
+ const importedUser = await importUser(
1016
+ stUserImport,
1017
+ deps.stConfig.supertokens
1018
+ );
1019
+ superTokensUserId = importedUser.id;
1020
+ if (importedUser.loginMethods[0]?.recipeUserId) {
1021
+ recipeUserId = import_supertokens_node.default.convertToRecipeUserId(
1022
+ importedUser.loginMethods[0].recipeUserId
1023
+ );
1024
+ }
1025
+ } catch (err) {
1026
+ user = await import_supertokens_node.default.getUser(rowndUserId, userContext);
1027
+ if (!user) {
1028
+ throw err;
1029
+ }
1030
+ superTokensUserId = user.id;
1031
+ recipeUserId = user.loginMethods[0]?.recipeUserId;
1032
+ logDebugMessage(
1033
+ `User already migrated (race condition). tenantId: ${PUBLIC_TENANT_ID}, rowndUserId: ${rowndUserId}`
1034
+ );
1035
+ }
1036
+ logDebugMessage(
1037
+ `User migrated successfully. tenantId: ${PUBLIC_TENANT_ID}, rowndUserId: ${rowndUserId}`
1038
+ );
1039
+ } else {
1040
+ superTokensUserId = user.id;
1041
+ recipeUserId = user.loginMethods[0]?.recipeUserId;
1042
+ logDebugMessage(
1043
+ `User already migrated. tenantId: ${PUBLIC_TENANT_ID}, rowndUserId: ${rowndUserId}`
1044
+ );
1045
+ }
1046
+ if (superTokensUserId) {
1047
+ await recordRowndAppVariantForUser(superTokensUserId, appVariantId);
1048
+ }
1049
+ if (!recipeUserId) {
1050
+ throw new Error("User not found or has no login methods");
1051
+ }
1052
+ await import_session.default.createNewSession(
1053
+ req,
1054
+ res,
1055
+ PUBLIC_TENANT_ID,
1056
+ recipeUserId,
1057
+ {
1058
+ ...buildRowndAudience({}, appVariantId)
1059
+ },
1060
+ {},
1061
+ userContext
1062
+ );
1063
+ logDebugMessage(
1064
+ `Session migrated successfully. tenantId: ${PUBLIC_TENANT_ID}, userId: ${superTokensUserId}`
1065
+ );
1066
+ deps.telemetryClient.recordSuccess({
1067
+ outcome: "success",
1068
+ durationMs: Date.now() - startedAt,
1069
+ tenantId,
1070
+ rowndUserId,
1071
+ superTokensUserId
1072
+ });
1073
+ return { status: "OK" };
1074
+ } catch (error) {
1075
+ logDebugMessage(`Migration failed. Error: ${getErrorMessage(error)}`);
1076
+ deps.telemetryClient.recordError({
1077
+ error,
1078
+ startedAt,
1079
+ tenantId,
1080
+ rowndUserId,
1081
+ superTokensUserId
1082
+ });
1083
+ return {
1084
+ status: "ERROR",
1085
+ message: error instanceof RowndPluginError ? error.message : "Migration failed"
1086
+ };
1087
+ }
1088
+ };
1089
+ }
1090
+ function handleGetUser() {
1091
+ return async (_req, _res, maybeSession) => {
1092
+ const session = requireSession(maybeSession);
1093
+ return {
1094
+ status: "OK",
1095
+ ...await getUserById(session.getUserId())
1096
+ };
1097
+ };
1098
+ }
1099
+ function handleUpdateUser() {
1100
+ return async (req, _res, maybeSession, userContext) => {
1101
+ const session = requireSession(maybeSession);
1102
+ const appVariantId = getRequestedAppVariantIdFromRequest(req);
1103
+ assertRowndAppVariantIsConfigured(appVariantId);
1104
+ const payload = parseUpdateUserBody(await getJsonBody(req));
1105
+ const inputData = payload.data ?? {};
1106
+ const requestUserContext = {
1107
+ ...userContext,
1108
+ ...payload.context
1109
+ };
1110
+ const { email, ...dataWithoutEmail } = inputData;
1111
+ const hasEmailUpdate = hasOwn(inputData, "email") && typeof email === "string";
1112
+ const permissionError = validateWritableFields(
1113
+ Object.keys(dataWithoutEmail)
1114
+ );
1115
+ if (permissionError) {
1116
+ return permissionError;
1117
+ }
1118
+ if (Object.keys(dataWithoutEmail).length > 0) {
1119
+ await updateUserData(session.getUserId(), dataWithoutEmail);
1120
+ }
1121
+ if (hasEmailUpdate) {
1122
+ return {
1123
+ status: "OK",
1124
+ ...await startPendingEmailVerification({
1125
+ userId: session.getUserId(),
1126
+ recipeUserId: session.getRecipeUserId(),
1127
+ tenantId: session.getTenantId(),
1128
+ email,
1129
+ pendingVerificationId: (0, import_crypto.randomUUID)(),
1130
+ userContext: appVariantId ? { ...requestUserContext, rowndAppVariantId: appVariantId } : requestUserContext
1131
+ })
1132
+ };
1133
+ }
1134
+ return {
1135
+ status: "OK",
1136
+ ...await getUserById(session.getUserId())
1137
+ };
1138
+ };
1139
+ }
1140
+ function handleDeleteUser() {
1141
+ return async (_req, _res, maybeSession) => {
1142
+ const session = requireSession(maybeSession);
1143
+ await import_supertokens_node.default.deleteUser(session.getUserId(), true);
1144
+ return { status: "OK" };
1145
+ };
1146
+ }
1147
+ function handleSignOut() {
1148
+ return async (_req, _res, maybeSession, userContext) => {
1149
+ const session = requireSession(maybeSession);
1150
+ await import_session.default.revokeAllSessionsForUser(
1151
+ session.getUserId(),
1152
+ true,
1153
+ session.getTenantId(),
1154
+ userContext
1155
+ );
1156
+ return { status: "OK" };
1157
+ };
1158
+ }
1159
+ function handleGetUserMeta() {
1160
+ return async (_req, _res, maybeSession) => {
1161
+ const session = requireSession(maybeSession);
1162
+ const metadata = await getUserMetadata(session.getUserId());
1163
+ return {
1164
+ status: "OK",
1165
+ id: session.getUserId(),
1166
+ meta: Object.fromEntries(
1167
+ Object.entries(metadata).filter(
1168
+ ([key]) => !isInternalMetadataField(key)
1169
+ )
1170
+ )
1171
+ };
1172
+ };
1173
+ }
1174
+ function handleUpdateUserMeta() {
1175
+ return async (req, _res, maybeSession) => {
1176
+ const session = requireSession(maybeSession);
1177
+ const payload = parseUpdateMetaBody(await getJsonBody(req));
1178
+ const internalField = Object.keys(payload.meta ?? {}).find(
1179
+ isInternalMetadataField
1180
+ );
1181
+ if (internalField) {
1182
+ return {
1183
+ status: "ERROR",
1184
+ code: 403,
1185
+ message: `field is not writable: ${internalField}`
1186
+ };
1187
+ }
1188
+ return {
1189
+ status: "OK",
1190
+ ...await updateUserMetadata(session.getUserId(), payload.meta ?? {})
1191
+ };
1192
+ };
1193
+ }
1194
+ function handleGetUserField() {
1195
+ return async (req, _res, maybeSession) => {
1196
+ const session = requireSession(maybeSession);
1197
+ const field = req.getKeyValueFromQuery("field");
1198
+ if (!field) {
1199
+ return missingFieldResponse();
1200
+ }
1201
+ const user = await getUserById(session.getUserId());
1202
+ return {
1203
+ status: "OK",
1204
+ value: user.data[field]
1205
+ };
1206
+ };
1207
+ }
1208
+ function handleUpdateUserField() {
1209
+ return async (req, _res, maybeSession, userContext) => {
1210
+ const session = requireSession(maybeSession);
1211
+ const appVariantId = getRequestedAppVariantIdFromRequest(req);
1212
+ assertRowndAppVariantIsConfigured(appVariantId);
1213
+ const field = req.getKeyValueFromQuery("field");
1214
+ if (!field) {
1215
+ return missingFieldResponse();
1216
+ }
1217
+ const payload = parseUpdateFieldBody(await getJsonBody(req));
1218
+ if (field === "email" && typeof payload.value === "string") {
1219
+ return {
1220
+ status: "OK",
1221
+ ...await startPendingEmailVerification({
1222
+ userId: session.getUserId(),
1223
+ recipeUserId: session.getRecipeUserId(),
1224
+ tenantId: session.getTenantId(),
1225
+ email: payload.value,
1226
+ pendingVerificationId: (0, import_crypto.randomUUID)(),
1227
+ userContext: appVariantId ? { ...userContext, rowndAppVariantId: appVariantId } : userContext
1228
+ })
1229
+ };
1230
+ }
1231
+ const permissionError = validateWritableFields([field]);
1232
+ if (permissionError) {
1233
+ return permissionError;
1234
+ }
1235
+ return {
1236
+ status: "OK",
1237
+ ...await updateUserData(session.getUserId(), {
1238
+ [field]: payload.value
1239
+ })
1240
+ };
1241
+ };
1242
+ }
1243
+ function requireSession(session) {
1244
+ if (!session) {
1245
+ throw new Error("Session not found");
1246
+ }
1247
+ return session;
1248
+ }
1249
+ async function getJsonBody(req) {
1250
+ return req.getJSONBody();
1251
+ }
1252
+ function parseGuestBody(value) {
1253
+ if (!isJsonRecord(value)) {
1254
+ return {};
1255
+ }
1256
+ return {
1257
+ authLevel: typeof value.auth_level === "string" ? value.auth_level : void 0
1258
+ };
1259
+ }
1260
+ function parseUpdateUserBody(value) {
1261
+ if (!isJsonRecord(value) || !isJsonRecord(value.data)) {
1262
+ return {};
1263
+ }
1264
+ return {
1265
+ data: value.data,
1266
+ ...isJsonRecord(value.context) ? { context: value.context } : {}
1267
+ };
1268
+ }
1269
+ function parseUpdateMetaBody(value) {
1270
+ if (!isJsonRecord(value) || !isJsonRecord(value.meta)) {
1271
+ return {};
1272
+ }
1273
+ return { meta: value.meta };
1274
+ }
1275
+ function parseUpdateFieldBody(value) {
1276
+ if (!isJsonRecord(value) || !hasOwn(value, "value")) {
1277
+ return {};
1278
+ }
1279
+ return { value: value.value };
1280
+ }
1281
+ function validateWritableFields(fields) {
1282
+ const readOnlyField = fields.find((field) => !canUpdateUserDataField(field));
1283
+ if (!readOnlyField) {
1284
+ return void 0;
1285
+ }
1286
+ return {
1287
+ status: "ERROR",
1288
+ code: 403,
1289
+ message: `field is not writable: ${readOnlyField}`
1290
+ };
1291
+ }
1292
+ function missingFieldResponse() {
1293
+ return {
1294
+ status: "ERROR",
1295
+ code: 400,
1296
+ message: "field is required"
1297
+ };
1298
+ }
1299
+ function isJsonRecord(value) {
1300
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1301
+ }
1302
+ function hasOwn(value, key) {
1303
+ return Object.prototype.hasOwnProperty.call(value, key);
1304
+ }
1305
+ function getErrorMessage(error) {
1306
+ return error instanceof Error ? error.message : "Unknown error";
1307
+ }
1308
+ function mapRowndUserToSuperTokens(rowndUser) {
1309
+ const loginMethods = [];
1310
+ const rowndUserData = rowndUser.data || {};
1311
+ const rowndUserVerifiedData = rowndUser.verified_data || {};
1312
+ if (!rowndUserData.user_id) {
1313
+ throw new Error("Rownd user has no user_id");
1314
+ }
1315
+ if (rowndUserData.google_id) {
1316
+ if (!rowndUserData.email) {
1317
+ throw new Error("Rownd Google user is missing email");
1318
+ }
1319
+ loginMethods.push({
1320
+ recipeId: "thirdparty",
1321
+ thirdPartyId: "google",
1322
+ thirdPartyUserId: rowndUserData.google_id,
1323
+ email: rowndUserData.email,
1324
+ isVerified: !!rowndUserVerifiedData.google_id
1325
+ });
1326
+ }
1327
+ if (rowndUserData.apple_id) {
1328
+ if (!rowndUserData.email) {
1329
+ throw new Error("Rownd Apple user is missing email");
1330
+ }
1331
+ loginMethods.push({
1332
+ recipeId: "thirdparty",
1333
+ thirdPartyId: "apple",
1334
+ thirdPartyUserId: rowndUserData.apple_id,
1335
+ email: rowndUserData.email,
1336
+ isVerified: !!rowndUserVerifiedData.apple_id
1337
+ });
1338
+ }
1339
+ if (rowndUserData.phone_number) {
1340
+ loginMethods.push({
1341
+ recipeId: "passwordless",
1342
+ phoneNumber: rowndUserData.phone_number,
1343
+ isVerified: !!rowndUserVerifiedData.phone_number
1344
+ });
1345
+ }
1346
+ if (rowndUserData.email && !rowndUserData.google_id && !rowndUserData.apple_id) {
1347
+ loginMethods.push({
1348
+ recipeId: "passwordless",
1349
+ email: rowndUserData.email,
1350
+ isVerified: !!rowndUserVerifiedData.email
1351
+ });
1352
+ }
1353
+ let authLevel = rowndUser.auth_level;
1354
+ if (loginMethods.length === 0) {
1355
+ const thirdPartyId = authLevel === GUEST_AUTH_METHOD_ID ? GUEST_AUTH_METHOD_ID : ANONYMOUS_AUTH_METHOD_ID;
1356
+ if (!authLevel) authLevel = thirdPartyId;
1357
+ loginMethods.push({
1358
+ recipeId: "thirdparty",
1359
+ thirdPartyId,
1360
+ thirdPartyUserId: rowndUserData.user_id,
1361
+ email: `${rowndUserData.user_id}@anonymous.local`,
1362
+ isVerified: false
1363
+ });
1364
+ }
1365
+ const userMetadata = buildRowndUserMetadata(rowndUser);
1366
+ return {
1367
+ externalUserId: rowndUserData.user_id,
1368
+ loginMethods,
1369
+ userMetadata
1370
+ };
1371
+ }
1372
+ async function importUser(stUser, config2) {
1373
+ const headers = {
1374
+ "Content-Type": "application/json"
1375
+ };
1376
+ if (config2.apiKey) {
1377
+ headers["api-key"] = config2.apiKey;
1378
+ }
1379
+ const response = await fetch(`${config2.connectionURI}/bulk-import/import`, {
1380
+ method: "POST",
1381
+ headers,
1382
+ body: JSON.stringify(stUser)
1383
+ });
1384
+ if (!response.ok) {
1385
+ const errorText = await response.text();
1386
+ throw new Error(
1387
+ `Bulk import failed with status ${response.status}: ${errorText}`
1388
+ );
1389
+ }
1390
+ const importResponse = await response.json();
1391
+ if (importResponse.status !== "OK" || !importResponse.user) {
1392
+ throw new Error(
1393
+ `Bulk import failed: ${importResponse.message || "Missing user in response"}`
1394
+ );
1395
+ }
1396
+ return importResponse.user;
1397
+ }
1398
+ async function validateRowndToken(token) {
1399
+ const client = getRowndClient();
1400
+ const tokenInfo = await client.validateToken(token);
1401
+ return tokenInfo.user_id;
1402
+ }
1403
+ async function fetchRowndUserInfo(userId) {
1404
+ const client = getRowndClient();
1405
+ const rowndUser = await client.fetchUserInfo({ user_id: userId });
1406
+ if (!rowndUser) {
1407
+ throw new RowndPluginError("ROWND_USER_NOT_FOUND");
1408
+ }
1409
+ return rowndUser;
1410
+ }
1411
+ var IDENTITY_USER_DATA_FIELDS = /* @__PURE__ */ new Set([
1412
+ "user_id",
1413
+ "email",
1414
+ "phone_number",
1415
+ "google_id",
1416
+ "apple_id"
1417
+ ]);
1418
+ var INTERNAL_METADATA_FIELDS = /* @__PURE__ */ new Set([
1419
+ "original_rownd_user",
1420
+ "rownd_pending_verification"
1421
+ ]);
1422
+ function isIdentityField(field) {
1423
+ return IDENTITY_USER_DATA_FIELDS.has(field);
1424
+ }
1425
+ function isInternalMetadataField(field) {
1426
+ return INTERNAL_METADATA_FIELDS.has(field);
1427
+ }
1428
+ function getStringList(value) {
1429
+ if (Array.isArray(value)) {
1430
+ return value.filter((entry) => typeof entry === "string");
1431
+ }
1432
+ return typeof value === "string" ? [value] : [];
1433
+ }
1434
+ function getRequestedAppVariantIdFromRequest(req) {
1435
+ return req.getKeyValueFromQuery("app_variant_id");
1436
+ }
1437
+ function getRequestedDisplayContextFromRequest(req) {
1438
+ const displayContext = req.getKeyValueFromQuery("rownd_display_context");
1439
+ return displayContext === "browser" || displayContext === "mobile_app" || displayContext === "customer_web_view" ? displayContext : void 0;
1440
+ }
1441
+ function getRequestedRedirectToPathFromRequest(req) {
1442
+ const redirectToPath = req.getKeyValueFromQuery("rownd_redirect_to_path");
1443
+ return typeof redirectToPath === "string" && redirectToPath.length > 0 ? redirectToPath : void 0;
1444
+ }
1445
+ function assertRowndAppVariantIsConfigured(appVariantId) {
1446
+ if (!appVariantId) {
1447
+ return;
1448
+ }
1449
+ if (pluginConfig?.subBrands && !pluginConfig.subBrands[appVariantId]) {
1450
+ throw new Error(`Unknown Rownd app variant: ${appVariantId}`);
1451
+ }
1452
+ }
1453
+ async function recordRowndAppVariantForUser(userId, appVariantId) {
1454
+ if (!appVariantId) {
1455
+ return;
1456
+ }
1457
+ assertRowndAppVariantIsConfigured(appVariantId);
1458
+ const metadata = await getUserMetadata(userId);
1459
+ const originalRowndUser = isJsonRecord(metadata.original_rownd_user) ? metadata.original_rownd_user : {};
1460
+ const attributes = isJsonRecord(originalRowndUser.attributes) ? originalRowndUser.attributes : {};
1461
+ const appVariants = getStringList(attributes["rownd:app_variants"]);
1462
+ if (appVariants.includes(appVariantId)) {
1463
+ return;
1464
+ }
1465
+ await import_usermetadata2.default.updateUserMetadata(userId, {
1466
+ ...metadata,
1467
+ original_rownd_user: {
1468
+ ...originalRowndUser,
1469
+ data: isJsonRecord(originalRowndUser.data) ? originalRowndUser.data : { user_id: userId },
1470
+ verified_data: isJsonRecord(originalRowndUser.verified_data) ? originalRowndUser.verified_data : {},
1471
+ attributes: {
1472
+ ...attributes,
1473
+ "rownd:app_variants": [...appVariants, appVariantId]
1474
+ }
1475
+ }
1476
+ });
1477
+ }
1478
+ function buildRowndUserMetadata(rowndUser) {
1479
+ const metadata = {
1480
+ ...rowndUser.meta || {},
1481
+ original_rownd_user: rowndUser
1482
+ };
1483
+ for (const [key, value] of Object.entries(rowndUser.data || {})) {
1484
+ if (!isIdentityField(key) && value !== void 0) {
1485
+ metadata[key] = value;
1486
+ }
1487
+ }
1488
+ return metadata;
1489
+ }
1490
+ var RowndIsAnonymousClaim = new import_claims.BooleanClaim({
1491
+ key: "is_anonymous",
1492
+ fetchValue: async (userId) => {
1493
+ const user = await import_supertokens_node.default.getUser(userId);
1494
+ const effectiveAuthLevel = getEffectiveAuthLevel(user);
1495
+ return effectiveAuthLevel === GUEST_AUTH_METHOD_ID;
1496
+ }
1497
+ });
1498
+ async function buildRowndSessionClaims(userId, currentPayload = {}, appVariantId) {
1499
+ const user = await import_supertokens_node.default.getUser(userId);
1500
+ const metadata = user ? await getUserMetadata(user.id) : void 0;
1501
+ const originalRowndUser = metadata?.original_rownd_user;
1502
+ const verifiedData = originalRowndUser?.verified_data;
1503
+ const authLevel = getEffectiveAuthLevel(
1504
+ user,
1505
+ originalRowndUser?.auth_level,
1506
+ verifiedData
1507
+ );
1508
+ const appUserId = getRowndAppUserId(userId, user, currentPayload, metadata);
1509
+ const isAnonymous = authLevel === GUEST_AUTH_METHOD_ID;
1510
+ const anonymousId = getAnonymousId(userId, user, metadata);
1511
+ const isVerifiedUser = authLevel !== "unverified";
1512
+ const audience = buildRowndAudience(currentPayload, appVariantId);
1513
+ const configuredClaims = buildConfiguredSessionClaims(metadata);
1514
+ return {
1515
+ ...audience,
1516
+ ...configuredClaims,
1517
+ app_user_id: appUserId,
1518
+ auth_level: authLevel,
1519
+ is_verified_user: isVerifiedUser,
1520
+ [ROWND_JWT_CLAIMS.AppUserId]: appUserId,
1521
+ [ROWND_JWT_CLAIMS.AuthLevel]: authLevel,
1522
+ [ROWND_JWT_CLAIMS.IsVerifiedUser]: isVerifiedUser,
1523
+ [ROWND_JWT_CLAIMS.IsAnonymous]: isAnonymous,
1524
+ ...anonymousId ? { anonymous_id: anonymousId } : {}
1525
+ };
1526
+ }
1527
+ function buildConfiguredSessionClaims(metadata) {
1528
+ if (!metadata) {
1529
+ return {};
1530
+ }
1531
+ const schema = pluginConfig?.schema || DEFAULT_ROWND_SCHEMA;
1532
+ const claims = {};
1533
+ for (const [key, field] of Object.entries(schema)) {
1534
+ if (field.include_in_session_claims !== true) {
1535
+ continue;
1536
+ }
1537
+ const value = metadata.original_rownd_user?.data?.[key] ?? metadata[key];
1538
+ if (value !== void 0) {
1539
+ claims[field.session_claim_name || key] = value;
1540
+ }
1541
+ }
1542
+ return claims;
1543
+ }
1544
+ function getRowndAppUserId(userId, user, currentPayload, metadata) {
1545
+ const originalUserId = metadata?.original_rownd_user?.data?.user_id;
1546
+ if (typeof originalUserId === "string") {
1547
+ return originalUserId;
1548
+ }
1549
+ if (typeof currentPayload.app_user_id === "string") {
1550
+ return currentPayload.app_user_id;
1551
+ }
1552
+ return user?.id || userId;
1553
+ }
1554
+ function buildRowndAudience(currentPayload, appVariantId) {
1555
+ const audience = getStringList(currentPayload.aud);
1556
+ const appId = pluginConfig?.appConfig?.id;
1557
+ if (appId) {
1558
+ audience.push(`app:${appId}`);
1559
+ }
1560
+ if (appVariantId) {
1561
+ audience.push(`app_variant:${appVariantId}`);
1562
+ }
1563
+ return audience.length > 0 ? { aud: [...new Set(audience)] } : {};
1564
+ }
1565
+ function getAnonymousId(userId, user, metadata) {
1566
+ const originalAnonymousId = metadata?.original_rownd_user?.data?.anonymous_id;
1567
+ if (typeof originalAnonymousId === "string") {
1568
+ return originalAnonymousId;
1569
+ }
1570
+ const anonymousMethod = user?.loginMethods.find((loginMethod) => {
1571
+ return loginMethod.recipeId === "thirdparty" && getThirdPartyId(loginMethod) === ANONYMOUS_AUTH_METHOD_ID;
1572
+ });
1573
+ const thirdPartyUserId = anonymousMethod ? getThirdPartyUserId(anonymousMethod) : void 0;
1574
+ return thirdPartyUserId || (hasAnonymousLoginMethod(user) ? `anon_${userId}` : void 0);
1575
+ }
1576
+ async function shouldLinkRowndAccounts(input) {
1577
+ const [newAccountInfo, , session] = input;
1578
+ if (!session) {
1579
+ return void 0;
1580
+ }
1581
+ const currentUser = await import_supertokens_node.default.getUser(session.getUserId());
1582
+ if (hasOnlyGuestLoginMethods(currentUser)) {
1583
+ return {
1584
+ shouldAutomaticallyLink: true,
1585
+ shouldRequireVerification: false
1586
+ };
1587
+ }
1588
+ if (!currentUser || isGuestAccountInfo(newAccountInfo)) {
1589
+ return void 0;
1590
+ }
1591
+ if (doesAccountInfoMatchAuthMethod(currentUser, newAccountInfo)) {
1592
+ return {
1593
+ shouldAutomaticallyLink: true,
1594
+ shouldRequireVerification: true
1595
+ };
1596
+ }
1597
+ return void 0;
1598
+ }
1599
+ async function getUserMetadata(userId) {
1600
+ const metadata = await import_usermetadata2.default.getUserMetadata(userId);
1601
+ return metadata.metadata || {};
1602
+ }
1603
+ function getPendingVerifications(metadata) {
1604
+ const pendingVerification = metadata.rownd_pending_verification;
1605
+ if (Array.isArray(pendingVerification)) {
1606
+ return pendingVerification.filter(isPendingVerification);
1607
+ }
1608
+ return [];
1609
+ }
1610
+ function isPendingVerification(value) {
1611
+ return isRecord(value) && typeof value.id === "string" && typeof value.field === "string" && typeof value.value === "string" && typeof value.created_at === "string";
1612
+ }
1613
+ async function getUserById(userId) {
1614
+ const metadata = await getUserMetadata(userId);
1615
+ const stUser = await import_supertokens_node.default.getUser(userId);
1616
+ if (!stUser) {
1617
+ throw new RowndPluginError("ROWND_USER_NOT_FOUND");
1618
+ }
1619
+ const originalRowndUser = metadata.original_rownd_user;
1620
+ const rowndUser = originalRowndUser?.data?.user_id || userId;
1621
+ const state = originalRowndUser?.state || "enabled";
1622
+ const dataFieldKeys = /* @__PURE__ */ new Set();
1623
+ const data = {
1624
+ user_id: userId
1625
+ };
1626
+ for (const [key, value] of Object.entries(originalRowndUser?.data || {})) {
1627
+ if (!isIdentityField(key)) {
1628
+ data[key] = value;
1629
+ dataFieldKeys.add(key);
1630
+ }
1631
+ }
1632
+ const schema = pluginConfig?.schema || DEFAULT_ROWND_SCHEMA;
1633
+ for (const key of Object.keys(schema)) {
1634
+ dataFieldKeys.add(key);
1635
+ if (!isInternalMetadataField(key) && !isIdentityField(key) && metadata[key] !== void 0) {
1636
+ data[key] = metadata[key];
1637
+ }
1638
+ }
1639
+ const verifiedData = {
1640
+ ...originalRowndUser?.verified_data || {}
1641
+ };
1642
+ let lastUsedAt = stUser.timeJoined;
1643
+ for (const method of stUser.loginMethods) {
1644
+ if (typeof method.lastUsed === "number" && method.lastUsed > lastUsedAt) {
1645
+ lastUsedAt = method.lastUsed;
1646
+ }
1647
+ if (method.recipeId === "passwordless") {
1648
+ if (method.email) {
1649
+ verifiedData.email = method.email;
1650
+ if (data.email === void 0) data.email = method.email;
1651
+ }
1652
+ if (method.phoneNumber) {
1653
+ verifiedData.phone_number = method.phoneNumber;
1654
+ if (data.phone_number === void 0)
1655
+ data.phone_number = method.phoneNumber;
1656
+ }
1657
+ } else if (method.recipeId === "thirdparty") {
1658
+ const thirdPartyId = getThirdPartyId(method);
1659
+ const thirdPartyUserId = getThirdPartyUserId(method);
1660
+ if (method.verified && method.email) {
1661
+ verifiedData.email = method.email;
1662
+ }
1663
+ if (method.email && data.email === void 0) {
1664
+ data.email = method.email;
1665
+ }
1666
+ if (thirdPartyId === "google" && thirdPartyUserId) {
1667
+ data.google_id = thirdPartyUserId;
1668
+ verifiedData.google_id = thirdPartyUserId;
1669
+ }
1670
+ if (thirdPartyId === "apple" && thirdPartyUserId) {
1671
+ data.apple_id = thirdPartyUserId;
1672
+ verifiedData.apple_id = thirdPartyUserId;
1673
+ }
1674
+ } else if (method.recipeId === "emailpassword") {
1675
+ if (method.email && data.email === void 0) {
1676
+ data.email = method.email;
1677
+ }
1678
+ }
1679
+ }
1680
+ if (verifiedData.email === true && typeof data.email === "string") {
1681
+ verifiedData.email = data.email;
1682
+ }
1683
+ if (verifiedData.phone_number === true && typeof data.phone_number === "string") {
1684
+ verifiedData.phone_number = data.phone_number;
1685
+ }
1686
+ const anonymousId = getAnonymousId(stUser.id, stUser, metadata);
1687
+ if (anonymousId && data.anonymous_id === void 0) {
1688
+ data.anonymous_id = anonymousId;
1689
+ }
1690
+ const authLevel = getEffectiveAuthLevel(
1691
+ stUser,
1692
+ originalRowndUser?.auth_level,
1693
+ verifiedData
1694
+ );
1695
+ for (const [key, field] of Object.entries(schema)) {
1696
+ if (data[key] === void 0 && field.type === "string") {
1697
+ data[key] = "";
1698
+ }
1699
+ }
1700
+ const mapMethod = (method) => {
1701
+ if (method.recipeId === "thirdparty") {
1702
+ if (getThirdPartyId(method) === "google") return "google";
1703
+ if (getThirdPartyId(method) === "apple") return "apple";
1704
+ } else if (method.recipeId === "passwordless") {
1705
+ if (method.email) return "email";
1706
+ if (method.phoneNumber) return "phone";
1707
+ } else if (method.recipeId === "emailpassword") {
1708
+ return "email";
1709
+ }
1710
+ return "email";
1711
+ };
1712
+ const sortedByJoined = [...stUser.loginMethods].sort(
1713
+ (a, b) => a.timeJoined - b.timeJoined
1714
+ );
1715
+ const sortedByLastUsed = [
1716
+ ...stUser.loginMethods
1717
+ ].sort((a, b) => (b.lastUsed || b.timeJoined) - (a.lastUsed || a.timeJoined));
1718
+ const firstMethod = sortedByJoined[0];
1719
+ const lastMethod = sortedByLastUsed[0];
1720
+ const metadataMeta = Object.fromEntries(
1721
+ Object.entries(metadata).filter(
1722
+ ([key]) => !isInternalMetadataField(key) && !dataFieldKeys.has(key)
1723
+ )
1724
+ );
1725
+ const meta = {
1726
+ ...metadataMeta,
1727
+ created: new Date(stUser.timeJoined).toISOString(),
1728
+ first_sign_in: new Date(stUser.timeJoined).toISOString(),
1729
+ last_sign_in: new Date(lastUsedAt).toISOString(),
1730
+ last_active: new Date(lastUsedAt).toISOString(),
1731
+ first_sign_in_method: firstMethod ? mapMethod(firstMethod) : "email",
1732
+ last_sign_in_method: lastMethod ? mapMethod(lastMethod) : "email"
1733
+ };
1734
+ return {
1735
+ rownd_user: rowndUser,
1736
+ data,
1737
+ meta,
1738
+ verified_data: verifiedData,
1739
+ state,
1740
+ auth_level: authLevel,
1741
+ redacted: [],
1742
+ groups: originalRowndUser?.groups || [],
1743
+ attributes: originalRowndUser?.attributes || {}
1744
+ };
1745
+ }
1746
+ async function updateUserData(userId, inputData) {
1747
+ const metadata = await getUserMetadata(userId);
1748
+ const updatedMetadata = {
1749
+ ...metadata,
1750
+ ...inputData
1751
+ };
1752
+ await import_usermetadata2.default.updateUserMetadata(userId, updatedMetadata);
1753
+ return getUserById(userId);
1754
+ }
1755
+ async function startPendingEmailVerification(input) {
1756
+ const metadata = await getUserMetadata(input.userId);
1757
+ const currentEmail = (await getUserById(input.userId)).data.email;
1758
+ if (currentEmail === input.email) {
1759
+ return getUserById(input.userId);
1760
+ }
1761
+ const pendingVerifications = getPendingVerifications(metadata);
1762
+ const pendingEmailVerifications = pendingVerifications.filter(
1763
+ (pendingVerification2) => pendingVerification2.field === "email"
1764
+ );
1765
+ for (const pendingVerification2 of pendingEmailVerifications) {
1766
+ await import_emailverification.default.revokeEmailVerificationTokens(
1767
+ input.tenantId,
1768
+ input.recipeUserId,
1769
+ pendingVerification2.value,
1770
+ input.userContext
1771
+ );
1772
+ }
1773
+ const pendingVerification = {
1774
+ id: input.pendingVerificationId,
1775
+ field: "email",
1776
+ value: input.email,
1777
+ created_at: (/* @__PURE__ */ new Date()).toISOString()
1778
+ };
1779
+ await import_usermetadata2.default.updateUserMetadata(input.userId, {
1780
+ ...metadata,
1781
+ rownd_pending_verification: [
1782
+ ...pendingVerifications.filter(
1783
+ (pendingVerification2) => pendingVerification2.field !== "email"
1784
+ ),
1785
+ pendingVerification
1786
+ ]
1787
+ });
1788
+ const response = await import_emailverification.default.sendEmailVerificationEmail(
1789
+ input.tenantId,
1790
+ input.userId,
1791
+ input.recipeUserId,
1792
+ input.email,
1793
+ {
1794
+ ...input.userContext,
1795
+ rowndPendingVerificationId: pendingVerification.id
1796
+ }
1797
+ );
1798
+ if (response.status === "EMAIL_ALREADY_VERIFIED_ERROR") {
1799
+ await completePendingEmailVerification({
1800
+ recipeUserId: input.recipeUserId,
1801
+ email: input.email,
1802
+ userContext: input.userContext
1803
+ });
1804
+ }
1805
+ return getUserById(input.userId);
1806
+ }
1807
+ async function completePendingEmailVerification(input) {
1808
+ const user = await import_supertokens_node.default.getUser(
1809
+ input.recipeUserId.getAsString(),
1810
+ input.userContext
1811
+ );
1812
+ const userId = user?.id ?? input.recipeUserId.getAsString();
1813
+ const metadata = await getUserMetadata(userId);
1814
+ const pendingVerifications = getPendingVerifications(metadata);
1815
+ const pendingVerification = pendingVerifications.find(
1816
+ (pendingVerification2) => pendingVerification2.field === "email" && pendingVerification2.value === input.email
1817
+ );
1818
+ if (!pendingVerification) {
1819
+ return;
1820
+ }
1821
+ let metadataUserId = userId;
1822
+ const passwordlessEmailMethod = getPasswordlessEmailLoginMethod(user);
1823
+ if (passwordlessEmailMethod) {
1824
+ const updateResult = await import_passwordless.default.updateUser({
1825
+ recipeUserId: passwordlessEmailMethod.recipeUserId,
1826
+ email: input.email,
1827
+ userContext: input.userContext
1828
+ });
1829
+ if (updateResult.status !== "OK") {
1830
+ throw new Error(
1831
+ `Failed to update verified email method: ${updateResult.status}`
1832
+ );
1833
+ }
1834
+ } else if (hasOnlyGuestLoginMethods(user)) {
1835
+ const isPasswordlessSignUpAllowed = await import_accountlinking.default.isSignUpAllowed(
1836
+ PUBLIC_TENANT_ID,
1837
+ {
1838
+ recipeId: "passwordless",
1839
+ email: input.email
1840
+ },
1841
+ true,
1842
+ void 0,
1843
+ input.userContext
1844
+ );
1845
+ if (!isPasswordlessSignUpAllowed) {
1846
+ throw new Error("Passwordless sign up is not allowed for this email");
1847
+ }
1848
+ const passwordlessUser = await import_passwordless.default.signInUp({
1849
+ email: input.email,
1850
+ tenantId: PUBLIC_TENANT_ID,
1851
+ userContext: input.userContext
1852
+ });
1853
+ const primaryUserResult = await import_accountlinking.default.createPrimaryUser(
1854
+ passwordlessUser.recipeUserId,
1855
+ input.userContext
1856
+ );
1857
+ const primaryUserId = primaryUserResult.status === "OK" ? primaryUserResult.user.id : primaryUserResult.status === "RECIPE_USER_ID_ALREADY_LINKED_WITH_PRIMARY_USER_ID_ERROR" ? primaryUserResult.primaryUserId : passwordlessUser.user.id;
1858
+ if (userId !== primaryUserId) {
1859
+ const linkResult = await import_accountlinking.default.linkAccounts(
1860
+ input.recipeUserId,
1861
+ primaryUserId,
1862
+ input.userContext
1863
+ );
1864
+ if (linkResult.status !== "OK") {
1865
+ throw new Error(
1866
+ `Failed to link verified email method: ${linkResult.status}`
1867
+ );
1868
+ }
1869
+ }
1870
+ metadataUserId = primaryUserId;
1871
+ }
1872
+ const updatedMetadata = {
1873
+ ...metadata,
1874
+ ...metadata.original_rownd_user ? {
1875
+ original_rownd_user: {
1876
+ ...metadata.original_rownd_user,
1877
+ data: {
1878
+ ...metadata.original_rownd_user.data,
1879
+ email: input.email
1880
+ },
1881
+ verified_data: {
1882
+ ...metadata.original_rownd_user.verified_data,
1883
+ email: input.email
1884
+ }
1885
+ }
1886
+ } : {},
1887
+ rownd_pending_verification: pendingVerifications.filter(
1888
+ (verification) => verification !== pendingVerification
1889
+ )
1890
+ };
1891
+ await import_usermetadata2.default.updateUserMetadata(metadataUserId, updatedMetadata);
1892
+ }
1893
+ async function updateUserMetadata(userId, inputMeta) {
1894
+ const metadata = await getUserMetadata(userId);
1895
+ const updatedMetadata = {
1896
+ ...metadata,
1897
+ ...inputMeta
1898
+ };
1899
+ await import_usermetadata2.default.updateUserMetadata(userId, updatedMetadata);
1900
+ return {
1901
+ id: userId,
1902
+ meta: Object.fromEntries(
1903
+ Object.entries(updatedMetadata).filter(
1904
+ ([key]) => !isInternalMetadataField(key)
1905
+ )
1906
+ )
1907
+ };
1908
+ }
1909
+ function getThirdPartyId(method) {
1910
+ return method.thirdPartyId || method.thirdParty?.id;
1911
+ }
1912
+ function getThirdPartyUserId(method) {
1913
+ return method.thirdPartyUserId || method.thirdParty?.userId;
1914
+ }
1915
+ function getGuestAuthLevel(user) {
1916
+ const guestMethod = user?.loginMethods.find(isGuestLoginMethod);
1917
+ return guestMethod ? GUEST_AUTH_METHOD_ID : void 0;
1918
+ }
1919
+ function hasAnonymousLoginMethod(user) {
1920
+ return !!user?.loginMethods.some((loginMethod) => {
1921
+ return loginMethod.recipeId === "thirdparty" && getThirdPartyId(loginMethod) === ANONYMOUS_AUTH_METHOD_ID;
1922
+ });
1923
+ }
1924
+ function getPasswordlessEmailLoginMethod(user) {
1925
+ return user?.loginMethods.find((method) => {
1926
+ return method.recipeId === "passwordless" && !!method.email;
1927
+ });
1928
+ }
1929
+ function hasOnlyGuestLoginMethods(user) {
1930
+ return !!user?.loginMethods.length && user.loginMethods.every(isGuestLoginMethod);
1931
+ }
1932
+ function isGuestLoginMethod(method) {
1933
+ const thirdPartyId = getThirdPartyId(method);
1934
+ return method.recipeId === "thirdparty" && (thirdPartyId === GUEST_AUTH_METHOD_ID || thirdPartyId === ANONYMOUS_AUTH_METHOD_ID);
1935
+ }
1936
+ function isGuestAccountInfo(input) {
1937
+ return input?.recipeId === "thirdparty" && (input.thirdParty?.id === GUEST_AUTH_METHOD_ID || input.thirdParty?.id === ANONYMOUS_AUTH_METHOD_ID);
1938
+ }
1939
+ function doesAccountInfoMatchAuthMethod(user, accountInfo) {
1940
+ if (!user) {
1941
+ return false;
1942
+ }
1943
+ const normalizedEmail = accountInfo.email?.toLowerCase();
1944
+ if (normalizedEmail) {
1945
+ return user.loginMethods.some((method) => {
1946
+ if (isGuestLoginMethod(method) || !method.email) {
1947
+ return false;
1948
+ }
1949
+ return method.email.toLowerCase() === normalizedEmail;
1950
+ });
1951
+ }
1952
+ if (accountInfo.phoneNumber) {
1953
+ return user.loginMethods.some((method) => {
1954
+ return !isGuestLoginMethod(method) && method.phoneNumber === accountInfo.phoneNumber;
1955
+ });
1956
+ }
1957
+ return false;
1958
+ }
1959
+ function hasVerifiedRealLoginMethod(user) {
1960
+ return !!user?.loginMethods.some((method) => {
1961
+ if (isGuestLoginMethod(method)) {
1962
+ return false;
1963
+ }
1964
+ if (method.recipeId === "passwordless") {
1965
+ return !!(method.email || method.phoneNumber);
1966
+ }
1967
+ if (method.recipeId === "thirdparty") {
1968
+ return !!getThirdPartyUserId(method) && method.verified === true;
1969
+ }
1970
+ if (method.recipeId === "emailpassword") {
1971
+ return !!method.email && method.verified === true;
1972
+ }
1973
+ return method.verified === true;
1974
+ });
1975
+ }
1976
+ function getEffectiveAuthLevel(user, originalAuthLevel, verifiedData) {
1977
+ if (hasVerifiedRealLoginMethod(user)) {
1978
+ return "verified";
1979
+ }
1980
+ return getGuestAuthLevel(user) || originalAuthLevel || (verifiedData && Object.keys(verifiedData).length > 0 ? "verified" : "unverified");
1981
+ }
1982
+ function canUpdateUserDataField(field) {
1983
+ const schema = pluginConfig?.schema || DEFAULT_ROWND_SCHEMA;
1984
+ const schemaField = schema[field];
1985
+ if (!schemaField) {
1986
+ return false;
1987
+ }
1988
+ const ownedBy = field === "google_id" || field === "apple_id" ? "app" : schemaField.owned_by || "user";
1989
+ return ownedBy !== "app" && schemaField.read_only !== true;
1990
+ }
1991
+ var BUILTIN_SIGN_IN_METHOD_KEYS = [
1992
+ "email",
1993
+ "phone",
1994
+ "google",
1995
+ "apple",
1996
+ "anonymous"
1997
+ ];
1998
+ function normalizeSchemaField(key, field) {
1999
+ let ownedBy = field.owned_by;
2000
+ if (key === "google_id" || key === "apple_id") {
2001
+ ownedBy = "app";
2002
+ } else if (!ownedBy) {
2003
+ ownedBy = "user";
2004
+ }
2005
+ return {
2006
+ display_name: field.display_name,
2007
+ type: field.type,
2008
+ owned_by: ownedBy,
2009
+ user_visible: field.user_visible,
2010
+ read_only: field.read_only ?? ownedBy === "app",
2011
+ show_empty: field.show_empty ?? false
2012
+ };
2013
+ }
2014
+ var DEFAULT_PRIMARY_COLOR = "#5b5bd6";
2015
+ function buildSignInMethodsConfig(methodsArray) {
2016
+ const methods = (methodsArray ?? []).reduce(
2017
+ (acc, curr) => {
2018
+ acc[curr.method] = curr;
2019
+ return acc;
2020
+ },
2021
+ {}
2022
+ );
2023
+ const customProviders = Object.fromEntries(
2024
+ Object.entries(methods).filter(([key]) => !BUILTIN_SIGN_IN_METHOD_KEYS.includes(key)).map(([key, val]) => {
2025
+ return val ? [
2026
+ key,
2027
+ {
2028
+ enabled: true,
2029
+ display_name: getStringMethodProperty(val, "displayName") ?? key,
2030
+ icon_light_url: getStringMethodProperty(val, "iconLightUrl"),
2031
+ icon_dark_url: getStringMethodProperty(val, "iconDarkUrl")
2032
+ }
2033
+ ] : [key, void 0];
2034
+ }).filter(([, v]) => v !== void 0)
2035
+ );
2036
+ const googleMethod = methods.google;
2037
+ const appleMethod = methods.apple;
2038
+ const anonymousMethod = methods.anonymous;
2039
+ const anonymousType = getAnonymousType(anonymousMethod);
2040
+ const googleOneTap = getOneTapConfig(googleMethod);
2041
+ return {
2042
+ email: { enabled: !!methods.email },
2043
+ phone: { enabled: !!methods.phone },
2044
+ google: {
2045
+ enabled: !!googleMethod,
2046
+ client_id: getStringMethodProperty(googleMethod, "clientId") ?? "",
2047
+ ios_client_id: getStringMethodProperty(googleMethod, "iosClientId") ?? "",
2048
+ scopes: getStringArrayMethodProperty(googleMethod, "scopes") ?? [],
2049
+ ...getSignInFasterWithGoogle(googleMethod) ? { sign_in_faster_with_google: getSignInFasterWithGoogle(googleMethod) } : {},
2050
+ one_tap: {
2051
+ browser: {
2052
+ auto_prompt: googleOneTap?.browser?.autoPrompt ?? false,
2053
+ delay: googleOneTap?.browser?.delay ?? 7e3
2054
+ },
2055
+ mobile_app: {
2056
+ auto_prompt: googleOneTap?.mobileApp?.autoPrompt ?? false,
2057
+ delay: googleOneTap?.mobileApp?.delay ?? 7e3
2058
+ }
2059
+ }
2060
+ },
2061
+ apple: {
2062
+ enabled: !!appleMethod,
2063
+ client_id: getStringMethodProperty(appleMethod, "clientId") ?? ""
2064
+ },
2065
+ anonymous: {
2066
+ enabled: !!anonymousMethod && anonymousType !== "instant",
2067
+ ...anonymousMethod && anonymousType !== "instant" ? { type: anonymousType } : {},
2068
+ ...anonymousType !== "instant" && getStringMethodProperty(anonymousMethod, "displayName") !== void 0 ? {
2069
+ display_name: getStringMethodProperty(
2070
+ anonymousMethod,
2071
+ "displayName"
2072
+ )
2073
+ } : {},
2074
+ ...anonymousType !== "instant" && getStringMethodProperty(anonymousMethod, "iconLightUrl") !== void 0 ? {
2075
+ icon_light_url: getStringMethodProperty(
2076
+ anonymousMethod,
2077
+ "iconLightUrl"
2078
+ )
2079
+ } : {},
2080
+ ...anonymousType !== "instant" && getStringMethodProperty(anonymousMethod, "iconDarkUrl") !== void 0 ? {
2081
+ icon_dark_url: getStringMethodProperty(
2082
+ anonymousMethod,
2083
+ "iconDarkUrl"
2084
+ )
2085
+ } : {}
2086
+ },
2087
+ ...customProviders
2088
+ };
2089
+ }
2090
+ function isInstantAnonymousMethod(methods) {
2091
+ return (methods ?? []).some(
2092
+ (method) => method.method === "anonymous" && getAnonymousType(method) === "instant"
2093
+ );
2094
+ }
2095
+ function getAnonymousType(method) {
2096
+ const type = getStringMethodProperty(method, "type");
2097
+ return type === "instant" ? "instant" : "guest";
2098
+ }
2099
+ function getSignInFasterWithGoogle(method) {
2100
+ const value = getStringMethodProperty(method, "signInFasterWithGoogle");
2101
+ return value === "enabled" || value === "disabled" ? value : void 0;
2102
+ }
2103
+ function getMethodProperty(method, property) {
2104
+ if (!method) {
2105
+ return void 0;
2106
+ }
2107
+ return method[property];
2108
+ }
2109
+ function getStringMethodProperty(method, property) {
2110
+ const value = getMethodProperty(method, property);
2111
+ return typeof value === "string" ? value : void 0;
2112
+ }
2113
+ function getStringArrayMethodProperty(method, property) {
2114
+ const value = getMethodProperty(method, property);
2115
+ return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : void 0;
2116
+ }
2117
+ function getOneTapConfig(method) {
2118
+ const oneTap = getMethodProperty(method, "oneTap");
2119
+ if (!isRecord(oneTap)) {
2120
+ return void 0;
2121
+ }
2122
+ return {
2123
+ browser: parseOneTapPlatform(oneTap.browser),
2124
+ mobileApp: parseOneTapPlatform(oneTap.mobileApp)
2125
+ };
2126
+ }
2127
+ function parseOneTapPlatform(value) {
2128
+ if (!isRecord(value)) {
2129
+ return void 0;
2130
+ }
2131
+ return {
2132
+ autoPrompt: typeof value.autoPrompt === "boolean" ? value.autoPrompt : void 0,
2133
+ delay: typeof value.delay === "number" ? value.delay : void 0
2134
+ };
2135
+ }
2136
+ function isRecord(value) {
2137
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2138
+ }
2139
+ function getSubBrandVariant(app) {
2140
+ if (isRecord(app) && isRecord(app.variant) && typeof app.variant.id === "string") {
2141
+ return app.variant;
2142
+ }
2143
+ return void 0;
2144
+ }
2145
+ function mergeConfigInput(base, override) {
2146
+ const result = { ...base };
2147
+ for (const [key, value] of Object.entries(override)) {
2148
+ if (value === void 0) {
2149
+ continue;
2150
+ }
2151
+ const existing = result[key];
2152
+ result[key] = isRecord(existing) && isRecord(value) ? mergeConfigInput(existing, value) : value;
2153
+ }
2154
+ return result;
2155
+ }
2156
+ function buildAppConfig(config2, stConfig, appVariantId) {
2157
+ const userSchema = config2.schema ?? DEFAULT_ROWND_SCHEMA;
2158
+ const baseApp = config2.appConfig ?? {};
2159
+ const subBrand = appVariantId ? config2.subBrands?.[appVariantId] : void 0;
2160
+ const app = appVariantId ? subBrand && mergeConfigInput(baseApp, subBrand) : baseApp;
2161
+ if (!app) {
2162
+ return void 0;
2163
+ }
2164
+ const branding = app.branding ?? {};
2165
+ const auth = app.auth ?? {};
2166
+ const signInMethods = buildSignInMethodsConfig(app.signInMethods);
2167
+ const variant = getSubBrandVariant(app);
2168
+ const finalSchema = { ...userSchema };
2169
+ if (signInMethods.email.enabled && !finalSchema.email) {
2170
+ finalSchema.email = {
2171
+ display_name: "Email",
2172
+ type: "string",
2173
+ user_visible: true
2174
+ };
2175
+ }
2176
+ if (signInMethods.phone.enabled && !finalSchema.phone_number) {
2177
+ finalSchema.phone_number = {
2178
+ display_name: "Phone number",
2179
+ type: "string",
2180
+ user_visible: true
2181
+ };
2182
+ }
2183
+ if (signInMethods.google.enabled && !finalSchema.google_id) {
2184
+ finalSchema.google_id = {
2185
+ display_name: "Google ID",
2186
+ type: "string",
2187
+ user_visible: false
2188
+ };
2189
+ }
2190
+ if (signInMethods.apple.enabled && !finalSchema.apple_id) {
2191
+ finalSchema.apple_id = {
2192
+ display_name: "Apple ID",
2193
+ type: "string",
2194
+ user_visible: false
2195
+ };
2196
+ }
2197
+ return {
2198
+ config_type: appVariantId ? "variant" : "app",
2199
+ ...variant ? { variant } : {},
2200
+ app: {
2201
+ id: app.id ?? "",
2202
+ name: app.name ?? stConfig.appInfo.appName,
2203
+ icon: app.icon ?? "",
2204
+ ...app.userVerificationFields ? { user_verification_fields: app.userVerificationFields } : {},
2205
+ schema: Object.fromEntries(
2206
+ Object.entries(finalSchema).map(([key, field]) => [
2207
+ key,
2208
+ normalizeSchemaField(key, field)
2209
+ ])
2210
+ ),
2211
+ config: {
2212
+ ...app.capabilities ? { capabilities: app.capabilities } : {},
2213
+ ...app.web ? { web: app.web } : {},
2214
+ ...app.bottomSheet ? { bottom_sheet: app.bottomSheet } : {},
2215
+ ...app.profileStorageVersion ? { profile_storage_version: app.profileStorageVersion } : {},
2216
+ customizations: {
2217
+ primary_color: branding.primaryColor ?? DEFAULT_PRIMARY_COLOR,
2218
+ ...branding.logo ? { logo: branding.logo } : {},
2219
+ ...branding.logoDarkMode ? { logo_dark_mode: branding.logoDarkMode } : {},
2220
+ ...branding.animations ? { animations: branding.animations } : {}
2221
+ },
2222
+ hub: {
2223
+ ...app.allowedWebOrigins ? { allowed_web_origins: app.allowedWebOrigins } : {},
2224
+ customizations: {
2225
+ rounded_corners: branding.roundedCorners ?? true,
2226
+ ...branding.containerBorderRadius !== void 0 ? { container_border_radius: branding.containerBorderRadius } : {},
2227
+ ...branding.placement !== void 0 ? { placement: branding.placement } : {},
2228
+ ...branding.hubPrimaryColor !== void 0 ? { primary_color: branding.hubPrimaryColor } : {},
2229
+ ...branding.primaryColorDarkMode !== void 0 ? { primary_color_dark_mode: branding.primaryColorDarkMode } : {},
2230
+ ...branding.backgroundColor !== void 0 ? { background_color: branding.backgroundColor } : {},
2231
+ ...branding.fontFamily !== void 0 ? { font_family: branding.fontFamily } : {},
2232
+ ...branding.hideVerificationIcons !== void 0 ? { hide_verification_icons: branding.hideVerificationIcons } : {},
2233
+ visual_swoops: branding.visualSwoops ?? true,
2234
+ blur_background: branding.blurBackground ?? true,
2235
+ ...branding.blurBackgroundOpacity !== void 0 ? { blur_background_opacity: branding.blurBackgroundOpacity } : {},
2236
+ ...branding.offsetX !== void 0 ? { offset_x: branding.offsetX } : {},
2237
+ ...branding.offsetY !== void 0 ? { offset_y: branding.offsetY } : {},
2238
+ ...branding.propertyOverrides ? { property_overrides: branding.propertyOverrides } : {},
2239
+ dark_mode: branding.darkMode ?? "auto"
2240
+ },
2241
+ ...branding.customScripts ? { custom_scripts: branding.customScripts } : {},
2242
+ ...branding.customStyles ? { custom_styles: branding.customStyles } : {},
2243
+ auth: {
2244
+ email: buildAuthEmailConfig(auth.email),
2245
+ ...auth.mobile ? { mobile: buildAuthMobileConfig(auth.mobile) } : {},
2246
+ sign_in_methods: signInMethods,
2247
+ additional_fields: auth.additionalFields ?? [],
2248
+ ...auth.rememberSignInMethod !== void 0 ? { remember_sign_in_method: auth.rememberSignInMethod } : {},
2249
+ ...auth.useExplicitSignUpFlow !== void 0 ? { use_explicit_sign_up_flow: auth.useExplicitSignUpFlow } : {},
2250
+ ...auth.allowUnverifiedUsers !== void 0 ? { allow_unverified_users: auth.allowUnverifiedUsers } : {},
2251
+ ...auth.primarySignUpMethod ? { primary_sign_up_method: auth.primarySignUpMethod } : {},
2252
+ ...auth.preferredMethod ? { preferred_method: auth.preferredMethod } : {},
2253
+ ...auth.order ? { order: auth.order } : {},
2254
+ ...isInstantAnonymousMethod(app.signInMethods) ? { instant_user: { enabled: true } } : {},
2255
+ show_app_icon: branding.showAppIcon ?? false
2256
+ },
2257
+ legal: {
2258
+ ...app.legal?.companyName ? { company_name: app.legal.companyName } : {},
2259
+ ...app.legal?.privacyPolicyUrl ? { privacy_policy_url: app.legal.privacyPolicyUrl } : {},
2260
+ ...app.legal?.termsConditionsUrl ? { terms_conditions_url: app.legal.termsConditionsUrl } : {},
2261
+ ...app.legal?.supportEmail ? { support_email: app.legal.supportEmail } : {}
2262
+ },
2263
+ custom_content: {
2264
+ ...app.customContent?.signInModal ? {
2265
+ sign_in_modal: {
2266
+ ...app.customContent.signInModal.title ? { title: app.customContent.signInModal.title } : {},
2267
+ ...app.customContent.signInModal.subtitle ? { subtitle: app.customContent.signInModal.subtitle } : {},
2268
+ ...app.customContent.signInModal.signInTitle ? {
2269
+ sign_in_title: app.customContent.signInModal.signInTitle
2270
+ } : {},
2271
+ ...app.customContent.signInModal.signUpTitle ? {
2272
+ sign_up_title: app.customContent.signInModal.signUpTitle
2273
+ } : {},
2274
+ ...app.customContent.signInModal.signInSubtitle ? {
2275
+ sign_in_subtitle: app.customContent.signInModal.signInSubtitle
2276
+ } : {},
2277
+ ...app.customContent.signInModal.signUpSubtitle ? {
2278
+ sign_up_subtitle: app.customContent.signInModal.signUpSubtitle
2279
+ } : {},
2280
+ ...app.customContent.signInModal.signInButton ? {
2281
+ sign_in_button: app.customContent.signInModal.signInButton
2282
+ } : {},
2283
+ ...app.customContent.signInModal.signUpButton ? {
2284
+ sign_up_button: app.customContent.signInModal.signUpButton
2285
+ } : {}
2286
+ }
2287
+ } : {},
2288
+ ...app.customContent?.profileModal ? { profile_modal: app.customContent.profileModal } : {},
2289
+ ...app.customContent?.verificationModal ? {
2290
+ verification_modal: {
2291
+ ...app.customContent.verificationModal.title ? { title: app.customContent.verificationModal.title } : {},
2292
+ ...app.customContent.verificationModal.subtitle ? { subtitle: app.customContent.verificationModal.subtitle } : {}
2293
+ }
2294
+ } : {},
2295
+ ...app.customContent?.signInFailureModal ? {
2296
+ sign_in_failure_modal: {
2297
+ failure_message: app.customContent.signInFailureModal.failureMessage
2298
+ }
2299
+ } : {},
2300
+ ...app.customContent?.noAccountMessage ? { no_account_message: app.customContent.noAccountMessage } : {},
2301
+ ...app.customContent?.mobile ? { mobile: app.customContent.mobile } : {}
2302
+ },
2303
+ profile: {
2304
+ ...app.profile?.accountInformation ? { account_information: app.profile.accountInformation } : {},
2305
+ ...app.profile?.personalInformation ? { personal_information: app.profile.personalInformation } : {},
2306
+ ...app.profile?.preferences ? { preferences: app.profile.preferences } : {},
2307
+ ...app.profile?.signOutButton ? { sign_out_button: app.profile.signOutButton } : {},
2308
+ ...app.profile?.deleteAccountButton ? { delete_account_button: app.profile.deleteAccountButton } : {},
2309
+ ...app.profile?.addSignInMethodsButton ? { add_sign_in_methods_button: app.profile.addSignInMethodsButton } : {}
2310
+ }
2311
+ }
2312
+ }
2313
+ }
2314
+ };
2315
+ }
2316
+ function buildAuthEmailConfig(authEmail) {
2317
+ return {
2318
+ from_address: authEmail?.fromAddress ?? "no-reply@rownd.io",
2319
+ image: authEmail?.image ?? "",
2320
+ ...authEmail?.subject ? { subject: authEmail.subject } : {},
2321
+ ...authEmail?.callToActionText ? { call_to_action_text: authEmail.callToActionText } : {},
2322
+ ...authEmail?.verifyTemplate ? { verify_template: authEmail.verifyTemplate } : {},
2323
+ ...authEmail?.customContent ? { custom_content: authEmail.customContent } : {},
2324
+ ...authEmail?.customClosingContent ? { custom_closing_content: authEmail.customClosingContent } : {}
2325
+ };
2326
+ }
2327
+ function buildAuthMobileConfig(authMobile) {
2328
+ return {
2329
+ ...authMobile?.title ? { title: authMobile.title } : {},
2330
+ ...authMobile?.image ? { image: authMobile.image } : {},
2331
+ ...authMobile?.callToActionText ? { call_to_action_text: authMobile.callToActionText } : {},
2332
+ ...authMobile?.hyperlinkText ? { hyperlink_text: authMobile.hyperlinkText } : {},
2333
+ ...authMobile?.hyperlinkRedirectUrl ? { hyperlink_redirect_url: authMobile.hyperlinkRedirectUrl } : {},
2334
+ ...authMobile?.customContent ? { custom_content: authMobile.customContent } : {}
2335
+ };
2336
+ }
2337
+
2338
+ // src/plugin.ts
2339
+ var init = createPluginInitFunction(
2340
+ (pluginConfig2) => {
2341
+ const rowndClient2 = (0, import_node.createInstance)({
2342
+ app_key: pluginConfig2.rowndAppKey,
2343
+ app_secret: pluginConfig2.rowndAppSecret
2344
+ });
2345
+ const telemetryClient = createClient(pluginConfig2.telemetry);
2346
+ let hubBootstrapParams;
2347
+ const addHubBootstrapParams = (input, linkKey, targetPath) => {
2348
+ const appVariantId = input?.userContext?.rowndAppVariantId;
2349
+ const displayContext = input?.userContext?.rowndDisplayContext;
2350
+ const redirectToPath = input?.userContext?.rowndRedirectToPath;
2351
+ const bootstrapParams = {
2352
+ appKey: pluginConfig2.rowndAppKey,
2353
+ ...hubBootstrapParams ?? {},
2354
+ ...typeof appVariantId === "string" ? { appVariantId } : {},
2355
+ ...typeof displayContext === "string" ? { displayContext } : {},
2356
+ ...typeof redirectToPath === "string" ? { redirectToPath } : {}
2357
+ };
2358
+ return {
2359
+ ...input,
2360
+ [linkKey]: input[linkKey] ? rewriteLinkPath(input[linkKey], targetPath, bootstrapParams) : input[linkKey]
2361
+ };
2362
+ };
2363
+ setRowndClient(rowndClient2);
2364
+ setPluginConfig(pluginConfig2);
2365
+ if (pluginConfig2.enableDebugLogs) {
2366
+ enableDebugLogs();
2367
+ }
2368
+ logDebugMessage("Rownd plugin init complete");
2369
+ return {
2370
+ id: PLUGIN_ID,
2371
+ compatibleSDKVersions: PLUGIN_SDK_VERSION,
2372
+ init: async () => {
2373
+ if (!import_supertokens_node2.default.isRecipeInitialized("session")) {
2374
+ console.warn(
2375
+ "RowndMigrationPlugin: Session recipe is not initialized. Session migration will fail."
2376
+ );
2377
+ }
2378
+ if (!import_supertokens_node2.default.isRecipeInitialized("thirdparty")) {
2379
+ console.warn(
2380
+ "RowndMigrationPlugin: ThirdParty recipe is not initialized. Guest login will fail."
2381
+ );
2382
+ }
2383
+ if (!import_supertokens_node2.default.isRecipeInitialized("emailverification")) {
2384
+ console.warn(
2385
+ "RowndMigrationPlugin: EmailVerification recipe is not initialized. Verified email profile updates will fail."
2386
+ );
2387
+ }
2388
+ },
2389
+ routeHandlers(stConfig) {
2390
+ const apiBasePath = stConfig.appInfo.apiBasePath.getAsStringDangerous();
2391
+ hubBootstrapParams = {
2392
+ apiDomain: stConfig.appInfo.apiDomain.getAsStringDangerous(),
2393
+ apiBasePath
2394
+ };
2395
+ const routeHandlerDeps = {
2396
+ pluginConfig: pluginConfig2,
2397
+ stConfig,
2398
+ telemetryClient
2399
+ };
2400
+ return {
2401
+ status: "OK",
2402
+ routeHandlers: [
2403
+ {
2404
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/app-config`,
2405
+ method: "get",
2406
+ handler: withRequestHandler(
2407
+ handleGetAppConfig(routeHandlerDeps)
2408
+ )
2409
+ },
2410
+ {
2411
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/guest`,
2412
+ method: "post",
2413
+ handler: withRequestHandler(handleGuestLogin(routeHandlerDeps))
2414
+ },
2415
+ {
2416
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/migrate`,
2417
+ method: "post",
2418
+ handler: withRequestHandler(handleMigrate(routeHandlerDeps))
2419
+ },
2420
+ {
2421
+ path: `${apiBasePath}/plugin/migrate-session`,
2422
+ method: "post",
2423
+ handler: withRequestHandler(handleMigrate(routeHandlerDeps))
2424
+ },
2425
+ {
2426
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/signout`,
2427
+ method: "post",
2428
+ verifySessionOptions: {
2429
+ sessionRequired: true,
2430
+ checkDatabase: true
2431
+ },
2432
+ handler: withRequestHandler(handleSignOut())
2433
+ },
2434
+ {
2435
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/user`,
2436
+ method: "get",
2437
+ verifySessionOptions: { sessionRequired: true },
2438
+ handler: withRequestHandler(handleGetUser())
2439
+ },
2440
+ {
2441
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/user`,
2442
+ method: "put",
2443
+ verifySessionOptions: { sessionRequired: true },
2444
+ handler: withRequestHandler(handleUpdateUser())
2445
+ },
2446
+ {
2447
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/user`,
2448
+ method: "delete",
2449
+ verifySessionOptions: { sessionRequired: true },
2450
+ handler: withRequestHandler(handleDeleteUser())
2451
+ },
2452
+ {
2453
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/user/meta`,
2454
+ method: "get",
2455
+ verifySessionOptions: { sessionRequired: true },
2456
+ handler: withRequestHandler(handleGetUserMeta())
2457
+ },
2458
+ {
2459
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/user/meta`,
2460
+ method: "put",
2461
+ verifySessionOptions: { sessionRequired: true },
2462
+ handler: withRequestHandler(handleUpdateUserMeta())
2463
+ },
2464
+ {
2465
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/user/field`,
2466
+ method: "get",
2467
+ verifySessionOptions: { sessionRequired: true },
2468
+ handler: withRequestHandler(handleGetUserField())
2469
+ },
2470
+ {
2471
+ path: `${apiBasePath}${HANDLE_BASE_PATH}/user/field`,
2472
+ method: "put",
2473
+ verifySessionOptions: { sessionRequired: true },
2474
+ handler: withRequestHandler(handleUpdateUserField())
2475
+ }
2476
+ ]
2477
+ };
2478
+ },
2479
+ overrideMap: {
2480
+ passwordless: {
2481
+ config: (config2) => {
2482
+ const originalEmailDeliveryOverride = config2.emailDelivery?.override;
2483
+ const originalSmsDeliveryOverride = config2.smsDelivery?.override;
2484
+ return {
2485
+ ...config2,
2486
+ emailDelivery: {
2487
+ ...config2.emailDelivery,
2488
+ override: (originalImplementation, builder) => {
2489
+ const implementation = originalEmailDeliveryOverride ? originalEmailDeliveryOverride(
2490
+ originalImplementation,
2491
+ builder
2492
+ ) : originalImplementation;
2493
+ return {
2494
+ ...implementation,
2495
+ sendEmail: async function(input) {
2496
+ return implementation.sendEmail({
2497
+ ...addHubBootstrapParams(
2498
+ input,
2499
+ "urlWithLinkCode",
2500
+ "account/login"
2501
+ )
2502
+ });
2503
+ }
2504
+ };
2505
+ }
2506
+ },
2507
+ smsDelivery: {
2508
+ ...config2.smsDelivery,
2509
+ override: (originalImplementation, builder) => {
2510
+ const implementation = originalSmsDeliveryOverride ? originalSmsDeliveryOverride(
2511
+ originalImplementation,
2512
+ builder
2513
+ ) : originalImplementation;
2514
+ return {
2515
+ ...implementation,
2516
+ sendSms: async function(input) {
2517
+ return implementation.sendSms({
2518
+ ...addHubBootstrapParams(
2519
+ input,
2520
+ "urlWithLinkCode",
2521
+ "account/login"
2522
+ )
2523
+ });
2524
+ }
2525
+ };
2526
+ }
2527
+ }
2528
+ };
2529
+ },
2530
+ apis: (originalImplementation) => ({
2531
+ ...originalImplementation,
2532
+ createCodePOST: async (input) => {
2533
+ if (originalImplementation.createCodePOST === void 0) {
2534
+ throw new Error("Passwordless createCodePOST is unavailable");
2535
+ }
2536
+ const displayContext = getRequestedDisplayContextFromRequest(
2537
+ input.options.req
2538
+ );
2539
+ const redirectToPath = getRequestedRedirectToPathFromRequest(
2540
+ input.options.req
2541
+ );
2542
+ const appVariantId = getRequestedAppVariantIdFromRequest(
2543
+ input.options.req
2544
+ );
2545
+ assertRowndAppVariantIsConfigured(appVariantId);
2546
+ return originalImplementation.createCodePOST({
2547
+ ...input,
2548
+ userContext: displayContext || redirectToPath || appVariantId ? {
2549
+ ...input.userContext,
2550
+ ...appVariantId ? { rowndAppVariantId: appVariantId } : {},
2551
+ ...displayContext ? { rowndDisplayContext: displayContext } : {},
2552
+ ...redirectToPath ? { rowndRedirectToPath: redirectToPath } : {}
2553
+ } : input.userContext
2554
+ });
2555
+ },
2556
+ consumeCodePOST: async (input) => {
2557
+ if (originalImplementation.consumeCodePOST === void 0) {
2558
+ throw new Error(
2559
+ "Passwordless consumeCodePOST is unavailable"
2560
+ );
2561
+ }
2562
+ const appVariantId = getRequestedAppVariantIdFromRequest(
2563
+ input.options.req
2564
+ );
2565
+ assertRowndAppVariantIsConfigured(appVariantId);
2566
+ const response = await originalImplementation.consumeCodePOST({
2567
+ ...input,
2568
+ userContext: appVariantId ? { ...input.userContext, rowndAppVariantId: appVariantId } : input.userContext
2569
+ });
2570
+ if (response.status === "OK") {
2571
+ await recordRowndAppVariantForUser(
2572
+ response.user.id,
2573
+ appVariantId
2574
+ );
2575
+ }
2576
+ return response;
2577
+ }
2578
+ })
2579
+ },
2580
+ thirdparty: {
2581
+ apis: (originalImplementation) => ({
2582
+ ...originalImplementation,
2583
+ signInUpPOST: async (input) => {
2584
+ if (originalImplementation.signInUpPOST === void 0) {
2585
+ throw new Error("ThirdParty signInUpPOST is unavailable");
2586
+ }
2587
+ const appVariantId = getRequestedAppVariantIdFromRequest(
2588
+ input.options.req
2589
+ );
2590
+ assertRowndAppVariantIsConfigured(appVariantId);
2591
+ const response = await originalImplementation.signInUpPOST({
2592
+ ...input,
2593
+ userContext: appVariantId ? { ...input.userContext, rowndAppVariantId: appVariantId } : input.userContext
2594
+ });
2595
+ if (response.status === "OK") {
2596
+ await recordRowndAppVariantForUser(
2597
+ response.user.id,
2598
+ appVariantId
2599
+ );
2600
+ }
2601
+ return response;
2602
+ }
2603
+ })
2604
+ },
2605
+ accountlinking: {
2606
+ recipeInitRequired: true,
2607
+ config: (config2) => {
2608
+ const originalShouldDoAutomaticAccountLinking = config2.shouldDoAutomaticAccountLinking;
2609
+ return {
2610
+ ...config2,
2611
+ shouldDoAutomaticAccountLinking: async (...input) => {
2612
+ const rowndLinkingDecision = await shouldLinkRowndAccounts(input);
2613
+ if (rowndLinkingDecision) {
2614
+ return rowndLinkingDecision;
2615
+ }
2616
+ if (originalShouldDoAutomaticAccountLinking) {
2617
+ return originalShouldDoAutomaticAccountLinking(...input);
2618
+ }
2619
+ return {
2620
+ shouldAutomaticallyLink: false,
2621
+ shouldRequireVerification: false
2622
+ };
2623
+ }
2624
+ };
2625
+ }
2626
+ },
2627
+ session: {
2628
+ recipeInitRequired: true,
2629
+ functions: (originalImplementation) => ({
2630
+ ...originalImplementation,
2631
+ createNewSession: async (input) => {
2632
+ input.accessTokenPayload = {
2633
+ ...input.accessTokenPayload,
2634
+ ...await buildRowndSessionClaims(
2635
+ input.userId,
2636
+ input.accessTokenPayload
2637
+ ),
2638
+ ...await RowndIsAnonymousClaim.build(
2639
+ input.userId,
2640
+ input.recipeUserId,
2641
+ input.tenantId,
2642
+ input.accessTokenPayload,
2643
+ input.userContext
2644
+ )
2645
+ };
2646
+ return originalImplementation.createNewSession(input);
2647
+ }
2648
+ })
2649
+ },
2650
+ emailverification: {
2651
+ recipeInitRequired: true,
2652
+ config: (config2) => {
2653
+ const originalEmailDeliveryOverride = config2.emailDelivery?.override;
2654
+ return {
2655
+ ...config2,
2656
+ emailDelivery: {
2657
+ ...config2.emailDelivery,
2658
+ override: (originalImplementation, builder) => {
2659
+ const implementation = originalEmailDeliveryOverride ? originalEmailDeliveryOverride(
2660
+ originalImplementation,
2661
+ builder
2662
+ ) : originalImplementation;
2663
+ return {
2664
+ ...implementation,
2665
+ sendEmail: async (input) => {
2666
+ return implementation.sendEmail({
2667
+ ...addHubBootstrapParams(
2668
+ input,
2669
+ "emailVerifyLink",
2670
+ "account/verify-email"
2671
+ )
2672
+ });
2673
+ }
2674
+ };
2675
+ }
2676
+ }
2677
+ };
2678
+ },
2679
+ apis: (originalImplementation) => ({
2680
+ ...originalImplementation,
2681
+ verifyEmailPOST: async (input) => {
2682
+ if (originalImplementation.verifyEmailPOST === void 0) {
2683
+ throw new Error(
2684
+ "EmailVerification verifyEmailPOST is unavailable"
2685
+ );
2686
+ }
2687
+ const response = await originalImplementation.verifyEmailPOST(input);
2688
+ if (response.status === "OK") {
2689
+ await completePendingEmailVerification({
2690
+ recipeUserId: response.user.recipeUserId,
2691
+ email: response.user.email,
2692
+ userContext: input.userContext
2693
+ });
2694
+ }
2695
+ return response;
2696
+ }
2697
+ })
2698
+ }
2699
+ }
2700
+ };
2701
+ },
2702
+ () => ({}),
2703
+ (config2) => {
2704
+ if (!config2?.rowndAppKey || !config2?.rowndAppSecret) {
2705
+ throw new Error(
2706
+ "Missing rowndAppKey or rowndAppSecret in plugin config"
2707
+ );
2708
+ }
2709
+ if (config2.telemetry?.provider === "axiom") {
2710
+ if (!config2.telemetry.token || !config2.telemetry.dataset) {
2711
+ throw new Error(
2712
+ "Missing telemetry axiom token or dataset in plugin config"
2713
+ );
2714
+ }
2715
+ }
2716
+ if (config2.telemetry?.provider === "custom") {
2717
+ if (typeof config2.telemetry.factory !== "function") {
2718
+ throw new Error(
2719
+ "Missing telemetry custom factory function in plugin config"
2720
+ );
2721
+ }
2722
+ }
2723
+ return {
2724
+ rowndAppKey: config2.rowndAppKey,
2725
+ rowndAppSecret: config2.rowndAppSecret,
2726
+ enableDebugLogs: config2.enableDebugLogs,
2727
+ telemetry: config2.telemetry,
2728
+ schema: config2.schema,
2729
+ appConfig: config2.appConfig,
2730
+ subBrands: config2.subBrands
2731
+ };
2732
+ }
2733
+ );
2734
+
2735
+ // src/index.ts
2736
+ var index_default = { init };
2737
+ // Annotate the CommonJS export names for ESM import in node:
2738
+ 0 && (module.exports = {
2739
+ ANONYMOUS_AUTH_METHOD_ID,
2740
+ DEFAULT_ROWND_SCHEMA,
2741
+ GUEST_AUTH_METHOD_ID,
2742
+ HANDLE_BASE_PATH,
2743
+ PLUGIN_ID,
2744
+ PLUGIN_SDK_VERSION,
2745
+ PUBLIC_TENANT_ID,
2746
+ ROWND_JWT_CLAIMS,
2747
+ ROWND_PLUGIN_ERROR_MESSAGES,
2748
+ RowndPluginError,
2749
+ getRowndClient,
2750
+ init,
2751
+ setRowndClient
2752
+ });