@seamless-auth/express 0.1.2-beta.2 → 0.2.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.
Files changed (2) hide show
  1. package/dist/index.js +374 -5
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -216,9 +216,9 @@ async function register(req, res, opts) {
216
216
  setSessionCookie(
217
217
  res,
218
218
  {
219
- name: opts.registrationCookieName || "seamless-auth-registraion",
219
+ name: c.name,
220
220
  payload: c.value,
221
- domain: c.domain,
221
+ domain: c.domain ?? opts.cookieDomain,
222
222
  ttlSeconds: c.ttl
223
223
  },
224
224
  cookieSigner
@@ -233,6 +233,7 @@ async function register(req, res, opts) {
233
233
 
234
234
  // src/handlers/finishRegister.ts
235
235
  import { finishRegisterHandler } from "@seamless-auth/core/handlers/finishRegister";
236
+ import { verifyCookieJwt } from "@seamless-auth/core";
236
237
  async function finishRegister(req, res, opts) {
237
238
  const cookieSigner = {
238
239
  secret: opts.cookieSecret,
@@ -240,8 +241,24 @@ async function finishRegister(req, res, opts) {
240
241
  sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
241
242
  };
242
243
  const authorization = buildServiceAuthorization(req, opts);
244
+ const bootstrapToken = req.cookies?.["seamless_bootstrap_token"];
245
+ const headers = {};
246
+ if (bootstrapToken) {
247
+ const payload = verifyCookieJwt(bootstrapToken, opts.cookieSecret);
248
+ if (!payload || !payload.sub) {
249
+ res.status(401).json({
250
+ error: "Invalid or expired session"
251
+ });
252
+ return;
253
+ }
254
+ headers["cookie"] = `seamless_bootstrap_token=${payload.sub}`;
255
+ }
243
256
  const result = await finishRegisterHandler(
244
- { body: req.body, authorization },
257
+ {
258
+ body: req.body,
259
+ authorization,
260
+ headers
261
+ },
245
262
  {
246
263
  authServerUrl: opts.authServerUrl,
247
264
  cookieDomain: opts.cookieDomain,
@@ -346,10 +363,272 @@ async function pollMagicLinkConfirmation(req, res, opts) {
346
363
  res.status(result.status).json(result.body).end();
347
364
  }
348
365
 
366
+ // src/handlers/admin.ts
367
+ import {
368
+ getUsersHandler,
369
+ createUserHandler,
370
+ deleteUserHandler,
371
+ updateUserHandler,
372
+ getUserDetailHandler,
373
+ getUserAnomaliesHandler,
374
+ getAuthEventsHandler,
375
+ getCredentialCountHandler,
376
+ listAllSessionsHandler,
377
+ listUserSessionsHandler,
378
+ revokeAllUserSessionsHandler
379
+ } from "@seamless-auth/core/handlers/admin";
380
+ function handle(res, result) {
381
+ if (result.error) {
382
+ return res.status(result.status).json({ error: result.error });
383
+ }
384
+ return res.status(result.status).json(result.body);
385
+ }
386
+ var getUsers = async (req, res, opts) => handle(
387
+ res,
388
+ await getUsersHandler({
389
+ authServerUrl: opts.authServerUrl,
390
+ authorization: buildServiceAuthorization(req, opts)
391
+ })
392
+ );
393
+ var createUser = async (req, res, opts) => handle(
394
+ res,
395
+ await createUserHandler({
396
+ authServerUrl: opts.authServerUrl,
397
+ authorization: buildServiceAuthorization(req, opts),
398
+ body: req.body
399
+ })
400
+ );
401
+ var deleteUser = async (req, res, opts) => handle(
402
+ res,
403
+ await deleteUserHandler({
404
+ authServerUrl: opts.authServerUrl,
405
+ authorization: buildServiceAuthorization(req, opts)
406
+ })
407
+ );
408
+ var updateUser = async (req, res, opts) => handle(
409
+ res,
410
+ await updateUserHandler(req.params.userId, {
411
+ authServerUrl: opts.authServerUrl,
412
+ authorization: buildServiceAuthorization(req, opts),
413
+ body: req.body
414
+ })
415
+ );
416
+ var getUserDetail = async (req, res, opts) => handle(
417
+ res,
418
+ await getUserDetailHandler(req.params.userId, {
419
+ authServerUrl: opts.authServerUrl,
420
+ authorization: buildServiceAuthorization(req, opts)
421
+ })
422
+ );
423
+ var getUserAnomalies = async (req, res, opts) => handle(
424
+ res,
425
+ await getUserAnomaliesHandler(req.params.userId, {
426
+ authServerUrl: opts.authServerUrl,
427
+ authorization: buildServiceAuthorization(req, opts)
428
+ })
429
+ );
430
+ var getAuthEvents = async (req, res, opts) => handle(
431
+ res,
432
+ await getAuthEventsHandler({
433
+ authServerUrl: opts.authServerUrl,
434
+ authorization: buildServiceAuthorization(req, opts),
435
+ query: req.query
436
+ })
437
+ );
438
+ var getCredentialCount = async (req, res, opts) => handle(
439
+ res,
440
+ await getCredentialCountHandler({
441
+ authServerUrl: opts.authServerUrl,
442
+ authorization: buildServiceAuthorization(req, opts)
443
+ })
444
+ );
445
+ var listAllSessions = async (req, res, opts) => handle(
446
+ res,
447
+ await listAllSessionsHandler({
448
+ authServerUrl: opts.authServerUrl,
449
+ authorization: buildServiceAuthorization(req, opts),
450
+ query: req.query
451
+ })
452
+ );
453
+ var listUserSessions = async (req, res, opts) => handle(
454
+ res,
455
+ await listUserSessionsHandler(req.params.userId, {
456
+ authServerUrl: opts.authServerUrl,
457
+ authorization: buildServiceAuthorization(req, opts)
458
+ })
459
+ );
460
+ var revokeAllUserSessions = async (req, res, opts) => handle(
461
+ res,
462
+ await revokeAllUserSessionsHandler(req.params.userId, {
463
+ authServerUrl: opts.authServerUrl,
464
+ authorization: buildServiceAuthorization(req, opts)
465
+ })
466
+ );
467
+
349
468
  // src/createServer.ts
350
469
  import {
351
470
  authFetch
352
471
  } from "@seamless-auth/core";
472
+
473
+ // src/handlers/bootstrapAdmininvite.ts
474
+ import { bootstrapAdminInviteHandler } from "@seamless-auth/core/handlers/bootstrapAdminInvite";
475
+ async function bootstrapAdminInvite(req, res, opts) {
476
+ const result = await bootstrapAdminInviteHandler({
477
+ authServerUrl: opts.authServerUrl,
478
+ email: req.body.email,
479
+ authorization: req.headers["authorization"]
480
+ });
481
+ if (result.error) {
482
+ return res.status(result.status).json({ error: result.error });
483
+ }
484
+ res.status(result.status).json(result.body);
485
+ }
486
+
487
+ // src/handlers/systemConfig.ts
488
+ import {
489
+ getAvailableRolesHandler,
490
+ getSystemConfigAdminHandler,
491
+ updateSystemConfigHandler
492
+ } from "@seamless-auth/core/handlers/systemConfig";
493
+ async function getAvailableRoles(req, res, opts) {
494
+ const authorization = buildServiceAuthorization(req, opts);
495
+ const result = await getAvailableRolesHandler({
496
+ authServerUrl: opts.authServerUrl,
497
+ authorization
498
+ });
499
+ if (result.error) {
500
+ return res.status(result.status).json({ error: result.error });
501
+ }
502
+ res.status(result.status).json(result.body);
503
+ }
504
+ async function getSystemConfigAdmin(req, res, opts) {
505
+ const authorization = buildServiceAuthorization(req, opts);
506
+ const result = await getSystemConfigAdminHandler({
507
+ authServerUrl: opts.authServerUrl,
508
+ authorization
509
+ });
510
+ if (result.error) {
511
+ return res.status(result.status).json({ error: result.error });
512
+ }
513
+ res.status(result.status).json(result.body);
514
+ }
515
+ async function updateSystemConfig(req, res, opts) {
516
+ const authorization = buildServiceAuthorization(req, opts);
517
+ const result = await updateSystemConfigHandler({
518
+ authServerUrl: opts.authServerUrl,
519
+ authorization,
520
+ payload: req.body
521
+ });
522
+ if (result.error) {
523
+ return res.status(result.status).json({ error: result.error });
524
+ }
525
+ res.status(result.status).json(result.body);
526
+ }
527
+
528
+ // src/handlers/internalMetrics.ts
529
+ import {
530
+ getAuthEventSummaryHandler,
531
+ getAuthEventTimeseriesHandler,
532
+ getLoginStatsHandler,
533
+ getSecurityAnomaliesHandler,
534
+ getDashboardMetricsHandler,
535
+ getGroupedEventSummaryHandler
536
+ } from "@seamless-auth/core/handlers/internalMetrics";
537
+ function handle2(res, result) {
538
+ if (result.error) {
539
+ return res.status(result.status).json({ error: result.error });
540
+ }
541
+ return res.status(result.status).json(result.body);
542
+ }
543
+ async function getAuthEventSummary(req, res, opts) {
544
+ const authorization = buildServiceAuthorization(req, opts);
545
+ const result = await getAuthEventSummaryHandler({
546
+ authServerUrl: opts.authServerUrl,
547
+ authorization,
548
+ query: req.query
549
+ });
550
+ return handle2(res, result);
551
+ }
552
+ async function getAuthEventTimeseries(req, res, opts) {
553
+ const authorization = buildServiceAuthorization(req, opts);
554
+ const result = await getAuthEventTimeseriesHandler({
555
+ authServerUrl: opts.authServerUrl,
556
+ authorization,
557
+ query: req.query
558
+ });
559
+ return handle2(res, result);
560
+ }
561
+ async function getLoginStats(req, res, opts) {
562
+ const authorization = buildServiceAuthorization(req, opts);
563
+ const result = await getLoginStatsHandler({
564
+ authServerUrl: opts.authServerUrl,
565
+ authorization
566
+ });
567
+ return handle2(res, result);
568
+ }
569
+ async function getSecurityAnomalies(req, res, opts) {
570
+ const authorization = buildServiceAuthorization(req, opts);
571
+ const result = await getSecurityAnomaliesHandler({
572
+ authServerUrl: opts.authServerUrl,
573
+ authorization
574
+ });
575
+ return handle2(res, result);
576
+ }
577
+ async function getDashboardMetrics(req, res, opts) {
578
+ const authorization = buildServiceAuthorization(req, opts);
579
+ const result = await getDashboardMetricsHandler({
580
+ authServerUrl: opts.authServerUrl,
581
+ authorization
582
+ });
583
+ return handle2(res, result);
584
+ }
585
+ async function getGroupedEventSummary(req, res, opts) {
586
+ const authorization = buildServiceAuthorization(req, opts);
587
+ const result = await getGroupedEventSummaryHandler({
588
+ authServerUrl: opts.authServerUrl,
589
+ authorization
590
+ });
591
+ return handle2(res, result);
592
+ }
593
+
594
+ // src/handlers/sessions.ts
595
+ import {
596
+ listSessionsHandler,
597
+ revokeSessionHandler,
598
+ revokeAllSessionsHandler
599
+ } from "@seamless-auth/core/handlers/sessions";
600
+ function handle3(res, result) {
601
+ if (result.error) {
602
+ return res.status(result.status).json({ error: result.error });
603
+ }
604
+ return res.status(result.status).json(result.body);
605
+ }
606
+ async function listSessions(req, res, opts) {
607
+ const authorization = buildServiceAuthorization(req, opts);
608
+ const result = await listSessionsHandler({
609
+ authServerUrl: opts.authServerUrl,
610
+ authorization
611
+ });
612
+ return handle3(res, result);
613
+ }
614
+ async function revokeSession(req, res, opts) {
615
+ const authorization = buildServiceAuthorization(req, opts);
616
+ const result = await revokeSessionHandler(req.params.id, {
617
+ authServerUrl: opts.authServerUrl,
618
+ authorization
619
+ });
620
+ return handle3(res, result);
621
+ }
622
+ async function revokeAllSessions(req, res, opts) {
623
+ const authorization = buildServiceAuthorization(req, opts);
624
+ const result = await revokeAllSessionsHandler({
625
+ authServerUrl: opts.authServerUrl,
626
+ authorization
627
+ });
628
+ return handle3(res, result);
629
+ }
630
+
631
+ // src/createServer.ts
353
632
  function createSeamlessAuthServer(opts) {
354
633
  const r = express.Router();
355
634
  r.use(express.json());
@@ -473,11 +752,101 @@ function createSeamlessAuthServer(opts) {
473
752
  "/magic-link/check",
474
753
  (req, res) => pollMagicLinkConfirmation(req, res, resolvedOpts)
475
754
  );
755
+ r.post(
756
+ "/internal/bootstrap/admin-invite",
757
+ (req, res) => bootstrapAdminInvite(req, res, resolvedOpts)
758
+ );
759
+ r.get(
760
+ "/system-config/roles",
761
+ (req, res) => getAvailableRoles(req, res, resolvedOpts)
762
+ );
763
+ r.get(
764
+ "/system-config/admin",
765
+ (req, res) => getSystemConfigAdmin(req, res, resolvedOpts)
766
+ );
767
+ r.patch(
768
+ "/system-config/admin",
769
+ (req, res) => updateSystemConfig(req, res, resolvedOpts)
770
+ );
771
+ r.get(
772
+ "/internal/auth-events/summary",
773
+ (req, res) => getAuthEventSummary(req, res, resolvedOpts)
774
+ );
775
+ r.get(
776
+ "/internal/auth-events/timeseries",
777
+ (req, res) => getAuthEventTimeseries(req, res, resolvedOpts)
778
+ );
779
+ r.get(
780
+ "/internal/auth-events/login-stats",
781
+ (req, res) => getLoginStats(req, res, resolvedOpts)
782
+ );
783
+ r.get(
784
+ "/internal/security/anomalies",
785
+ (req, res) => getSecurityAnomalies(req, res, resolvedOpts)
786
+ );
787
+ r.get(
788
+ "/internal/metrics/dashboard",
789
+ (req, res) => getDashboardMetrics(req, res, resolvedOpts)
790
+ );
791
+ r.get(
792
+ "/internal/auth-events/grouped",
793
+ (req, res) => getGroupedEventSummary(req, res, resolvedOpts)
794
+ );
795
+ r.get("/admin/users", (req, res) => getUsers(req, res, resolvedOpts));
796
+ r.post(
797
+ "/admin/users",
798
+ (req, res) => createUser(req, res, resolvedOpts)
799
+ );
800
+ r.delete(
801
+ "/admin/users",
802
+ (req, res) => deleteUser(req, res, resolvedOpts)
803
+ );
804
+ r.patch(
805
+ "/admin/users/:userId",
806
+ (req, res) => updateUser(req, res, resolvedOpts)
807
+ );
808
+ r.get(
809
+ "/admin/users/:userId",
810
+ (req, res) => getUserDetail(req, res, resolvedOpts)
811
+ );
812
+ r.get(
813
+ "/admin/users/:userId/anomalies",
814
+ (req, res) => getUserAnomalies(req, res, resolvedOpts)
815
+ );
816
+ r.get(
817
+ "/admin/auth-events",
818
+ (req, res) => getAuthEvents(req, res, resolvedOpts)
819
+ );
820
+ r.get(
821
+ "/admin/credential-count",
822
+ (req, res) => getCredentialCount(req, res, resolvedOpts)
823
+ );
824
+ r.get(
825
+ "/admin/sessions",
826
+ (req, res) => listAllSessions(req, res, resolvedOpts)
827
+ );
828
+ r.get(
829
+ "/admin/sessions/:userId",
830
+ (req, res) => listUserSessions(req, res, resolvedOpts)
831
+ );
832
+ r.delete(
833
+ "/admin/sessions/:userId/revoke-all",
834
+ (req, res) => revokeAllUserSessions(req, res, resolvedOpts)
835
+ );
836
+ r.get("/sessions", (req, res) => listSessions(req, res, resolvedOpts));
837
+ r.delete(
838
+ "/sessions/:id",
839
+ (req, res) => revokeSession(req, res, resolvedOpts)
840
+ );
841
+ r.delete(
842
+ "/sessions",
843
+ (req, res) => revokeAllSessions(req, res, resolvedOpts)
844
+ );
476
845
  return r;
477
846
  }
478
847
 
479
848
  // src/middleware/requireAuth.ts
480
- import { verifyCookieJwt } from "@seamless-auth/core";
849
+ import { verifyCookieJwt as verifyCookieJwt2 } from "@seamless-auth/core";
481
850
  function requireAuth(opts) {
482
851
  const { cookieName = "seamless-access", cookieSecret } = opts;
483
852
  if (!cookieSecret) {
@@ -495,7 +864,7 @@ function requireAuth(opts) {
495
864
  });
496
865
  return;
497
866
  }
498
- const payload = verifyCookieJwt(token, cookieSecret);
867
+ const payload = verifyCookieJwt2(token, cookieSecret);
499
868
  if (!payload || !payload.sub) {
500
869
  res.status(401).json({
501
870
  error: "Invalid or expired session"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamless-auth/express",
3
- "version": "0.1.2-beta.2",
3
+ "version": "0.2.0",
4
4
  "description": "Express adapter for Seamless Auth passwordless authentication",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
@@ -37,7 +37,7 @@
37
37
  "express": ">=4.18.0"
38
38
  },
39
39
  "dependencies": {
40
- "@seamless-auth/core": "^0.2.1-beta.0",
40
+ "@seamless-auth/core": "^0.3.0",
41
41
  "cookie-parser": "^1.4.6",
42
42
  "jsonwebtoken": "^9.0.3"
43
43
  },