@absolutejs/auth 0.36.0 → 0.37.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 CHANGED
@@ -1,4 +1,19 @@
1
1
  // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
2
17
  var __require = import.meta.require;
3
18
 
4
19
  // node_modules/citra/dist/index.js
@@ -20771,6 +20786,132 @@ var switchActiveSession = ({
20771
20786
  };
20772
20787
  // src/tenancy.ts
20773
20788
  var hasOrganizationScope = (value) => typeof value.organizationId === "string" && value.organizationId.length > 0;
20789
+ // src/credentials/backgroundOps.ts
20790
+ var HIBP_BREACHED_ACCOUNT_URL = "https://haveibeenpwned.com/api/v3/breachedaccount/";
20791
+ var HIBP_USER_AGENT = "@absolutejs/auth breach scanner";
20792
+ var DEFAULT_PAUSE_MS = 1700;
20793
+ var HIBP_NOT_FOUND = 404;
20794
+ var HIBP_RATE_LIMITED = 429;
20795
+ var MS_PER_DAY = 86400000;
20796
+ var MS_PER_SECOND3 = 1000;
20797
+ var sleep = (delayMs) => new Promise((resolve) => {
20798
+ setTimeout(resolve, delayMs);
20799
+ });
20800
+ var isBreachRecord = (entry) => {
20801
+ if (typeof entry !== "object" || entry === null)
20802
+ return false;
20803
+ if (!("name" in entry))
20804
+ return false;
20805
+ const candidate = entry;
20806
+ return typeof candidate.name === "string";
20807
+ };
20808
+ var isBreachRecordArray = (value) => Array.isArray(value) && value.every(isBreachRecord);
20809
+ var checkEmailBreaches = async (email, apiKey, truncate) => {
20810
+ const url = `${HIBP_BREACHED_ACCOUNT_URL}${encodeURIComponent(email)}?truncateResponse=${truncate ? "true" : "false"}`;
20811
+ const response = await fetch(url, {
20812
+ headers: {
20813
+ "hibp-api-key": apiKey,
20814
+ "user-agent": HIBP_USER_AGENT
20815
+ }
20816
+ });
20817
+ if (response.status === HIBP_NOT_FOUND)
20818
+ return [];
20819
+ if (response.status === HIBP_RATE_LIMITED) {
20820
+ const retryAfter = Number(response.headers.get("retry-after") ?? "0");
20821
+ if (retryAfter > 0)
20822
+ await sleep(retryAfter * MS_PER_SECOND3);
20823
+ return [];
20824
+ }
20825
+ if (!response.ok)
20826
+ return [];
20827
+ const body = await response.json();
20828
+ if (!isBreachRecordArray(body))
20829
+ return [];
20830
+ return body;
20831
+ };
20832
+ var scanEmail = async (email, apiKey, truncate, onBreachFound) => {
20833
+ const breaches = await checkEmailBreaches(email, apiKey, truncate);
20834
+ if (breaches.length === 0)
20835
+ return false;
20836
+ await onBreachFound({ breaches, email });
20837
+ return true;
20838
+ };
20839
+ var scanPage = async (options) => {
20840
+ let scanned = 0;
20841
+ let breached = 0;
20842
+ for (const email of options.emails) {
20843
+ scanned += 1;
20844
+ const hit = await scanEmail(email, options.apiKey, options.truncate, options.onBreachFound);
20845
+ if (hit)
20846
+ breached += 1;
20847
+ await sleep(options.pauseMs);
20848
+ }
20849
+ return { breached, scanned };
20850
+ };
20851
+ var runEmailBreachScan = async (input) => {
20852
+ const pauseMs = input.pauseMs ?? DEFAULT_PAUSE_MS;
20853
+ const truncate = input.truncateResponse ?? true;
20854
+ let scanned = 0;
20855
+ let breached = 0;
20856
+ let cursor;
20857
+ do {
20858
+ const page = await input.iterateEmails(cursor);
20859
+ const tally = await scanPage({
20860
+ apiKey: input.hibpApiKey,
20861
+ emails: page.emails,
20862
+ onBreachFound: input.onBreachFound,
20863
+ pauseMs,
20864
+ truncate
20865
+ });
20866
+ scanned += tally.scanned;
20867
+ breached += tally.breached;
20868
+ cursor = page.nextCursor;
20869
+ } while (cursor !== undefined);
20870
+ const result = { breached, scanned };
20871
+ return result;
20872
+ };
20873
+ var pruneCandidate = async (candidate, cutoff, dryRun, onDelete) => {
20874
+ const reference = candidate.lastLoginAt ?? candidate.createdAt;
20875
+ if (reference === undefined || reference === null)
20876
+ return false;
20877
+ if (reference >= cutoff)
20878
+ return false;
20879
+ if (!dryRun)
20880
+ await onDelete(candidate.userId);
20881
+ return true;
20882
+ };
20883
+ var prunePage = async (options) => {
20884
+ const pruned = [];
20885
+ for (const candidate of options.candidates) {
20886
+ const removed = await pruneCandidate(candidate, options.cutoff, options.dryRun, options.onDelete);
20887
+ if (removed)
20888
+ pruned.push(candidate.userId);
20889
+ }
20890
+ return pruned;
20891
+ };
20892
+ var pruneInactiveUsers = async (input) => {
20893
+ const now = input.now?.() ?? Date.now();
20894
+ const thresholdMs = input.olderThanDays * MS_PER_DAY;
20895
+ const cutoff = now - thresholdMs;
20896
+ const dryRun = input.dryRun ?? false;
20897
+ const prunedUserIds = [];
20898
+ let scanned = 0;
20899
+ let cursor;
20900
+ do {
20901
+ const page = await input.iterateUsers(cursor);
20902
+ scanned += page.users.length;
20903
+ const removed = await prunePage({
20904
+ candidates: page.users,
20905
+ cutoff,
20906
+ dryRun,
20907
+ onDelete: input.onDelete
20908
+ });
20909
+ prunedUserIds.push(...removed);
20910
+ cursor = page.nextCursor;
20911
+ } while (cursor !== undefined);
20912
+ const result = { dryRun, prunedUserIds, scanned };
20913
+ return result;
20914
+ };
20774
20915
  // src/credentials/emailValidation.ts
20775
20916
  import { resolveMx } from "dns/promises";
20776
20917
  var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/u;
@@ -24373,6 +24514,7 @@ export {
24373
24514
  samlServiceProvidersTable,
24374
24515
  samlIdpRoutes,
24375
24516
  runMigrations,
24517
+ runEmailBreachScan,
24376
24518
  rotateVaultKey,
24377
24519
  rotateMfaEncryptionKey,
24378
24520
  rolesTable,
@@ -24400,6 +24542,7 @@ export {
24400
24542
  readUserInfoBearer,
24401
24543
  readSessionRing,
24402
24544
  pushAuthorizationRequest,
24545
+ pruneInactiveUsers,
24403
24546
  providers,
24404
24547
  providerOptions,
24405
24548
  protectRoutePlugin,
@@ -24703,5 +24846,5 @@ export {
24703
24846
  AuthIdentityConflictError
24704
24847
  };
24705
24848
 
24706
- //# debugId=1069DAAF739CAF9F64756E2164756E21
24849
+ //# debugId=26C38ACE51F8A69A64756E2164756E21
24707
24850
  //# sourceMappingURL=index.js.map