@objectstack/plugin-auth 6.5.0 → 6.6.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.mjs CHANGED
@@ -460,10 +460,56 @@ function buildDeviceAuthorizationPluginSchema() {
460
460
  }
461
461
 
462
462
  // src/auth-manager.ts
463
+ function isWebContainerRuntime() {
464
+ if (typeof globalThis === "undefined") return false;
465
+ const proc = globalThis.process;
466
+ return Boolean(proc?.versions?.webcontainer) || Boolean(proc?.env?.SHELL?.includes?.("jsh")) || Boolean(proc?.env?.STACKBLITZ);
467
+ }
468
+ var WebContainerRequestStateAsyncLocalStorage = class {
469
+ constructor() {
470
+ this.current = void 0;
471
+ }
472
+ run(store, fn) {
473
+ const prev = this.current;
474
+ this.current = store;
475
+ try {
476
+ const result = fn();
477
+ if (result && typeof result.then === "function") {
478
+ return result.finally(() => {
479
+ this.current = prev;
480
+ });
481
+ }
482
+ this.current = prev;
483
+ return result;
484
+ } catch (err) {
485
+ this.current = prev;
486
+ throw err;
487
+ }
488
+ }
489
+ getStore() {
490
+ return this.current;
491
+ }
492
+ };
493
+ function installWebContainerRequestStatePolyfill() {
494
+ if (!isWebContainerRuntime()) return;
495
+ const sym = /* @__PURE__ */ Symbol.for("better-auth:global");
496
+ const g = globalThis;
497
+ if (!g[sym]) {
498
+ g[sym] = { version: "0.0.0-polyfill", epoch: 0, context: {} };
499
+ }
500
+ if (!g[sym].context) g[sym].context = {};
501
+ if (!g[sym].context.requestStateAsyncStorage) {
502
+ g[sym].context.requestStateAsyncStorage = new WebContainerRequestStateAsyncLocalStorage();
503
+ console.warn(
504
+ "[AuthManager] WebContainer detected: installed synchronous request-state polyfill (node:async_hooks AsyncLocalStorage does not propagate context across await in WebContainer)."
505
+ );
506
+ }
507
+ }
463
508
  var AuthManager = class {
464
509
  constructor(config) {
465
510
  this.auth = null;
466
511
  this.config = config;
512
+ installWebContainerRequestStatePolyfill();
467
513
  if (config.authInstance) {
468
514
  this.auth = config.authInstance;
469
515
  }
@@ -680,8 +726,7 @@ var AuthManager = class {
680
726
  * the native (fast) hasher and never load `@noble/hashes`.
681
727
  */
682
728
  async resolvePasswordHasher() {
683
- const isWebContainer = typeof globalThis !== "undefined" && (Boolean(globalThis.process?.versions?.webcontainer) || Boolean(globalThis.process?.env?.SHELL?.includes?.("jsh")) || Boolean(globalThis.process?.env?.STACKBLITZ));
684
- if (!isWebContainer) return void 0;
729
+ if (!isWebContainerRuntime()) return void 0;
685
730
  try {
686
731
  const { scryptAsync } = await import("@noble/hashes/scrypt.js");
687
732
  const PARAMS = { N: 16384, r: 16, p: 1, dkLen: 64, maxmem: 128 * 16384 * 16 * 2 };
@@ -1485,6 +1530,61 @@ var AuthPlugin = class {
1485
1530
  return c.json({ success: false, error: { code: "internal", message: err.message } }, 500);
1486
1531
  }
1487
1532
  });
1533
+ rawApp.post(`${basePath}/admin/oauth2/toggle-disabled`, async (c) => {
1534
+ try {
1535
+ let body = {};
1536
+ try {
1537
+ body = await c.req.json();
1538
+ } catch {
1539
+ body = {};
1540
+ }
1541
+ const clientId = body?.client_id;
1542
+ const disabled = body?.disabled;
1543
+ if (typeof clientId !== "string" || clientId.length === 0) {
1544
+ return c.json({ success: false, error: { code: "invalid_request", message: "client_id is required" } }, 400);
1545
+ }
1546
+ if (typeof disabled !== "boolean") {
1547
+ return c.json({ success: false, error: { code: "invalid_request", message: "disabled must be a boolean" } }, 400);
1548
+ }
1549
+ const authApi = await this.authManager.getApi();
1550
+ const session = await authApi.getSession({ headers: c.req.raw.headers });
1551
+ if (!session?.user?.id) {
1552
+ return c.json({ success: false, error: { code: "unauthorized", message: "Sign in first" } }, 401);
1553
+ }
1554
+ if (session.user.role !== "admin") {
1555
+ return c.json({ success: false, error: { code: "forbidden", message: "Admin role required" } }, 403);
1556
+ }
1557
+ const dataEngine = this.authManager.getDataEngine();
1558
+ if (!dataEngine) {
1559
+ return c.json({ success: false, error: { code: "unavailable", message: "Data engine unavailable" } }, 503);
1560
+ }
1561
+ const existing = await dataEngine.findOne("sys_oauth_application", {
1562
+ where: { client_id: clientId }
1563
+ });
1564
+ if (!existing) {
1565
+ return c.json({ success: false, error: { code: "not_found", message: "OAuth client not found" } }, 404);
1566
+ }
1567
+ const updated = await dataEngine.update("sys_oauth_application", {
1568
+ id: existing.id,
1569
+ disabled,
1570
+ updated_at: new Date(Math.floor(Date.now() / 1e3) * 1e3)
1571
+ });
1572
+ if (!updated) {
1573
+ return c.json({ success: false, error: { code: "internal", message: "Unable to update OAuth client" } }, 500);
1574
+ }
1575
+ return c.json({
1576
+ success: true,
1577
+ data: {
1578
+ client_id: clientId,
1579
+ disabled
1580
+ }
1581
+ });
1582
+ } catch (error) {
1583
+ const err = error instanceof Error ? error : new Error(String(error));
1584
+ ctx.logger.error("[AuthPlugin] toggle-disabled failed", err);
1585
+ return c.json({ success: false, error: { code: "internal", message: err.message } }, 500);
1586
+ }
1587
+ });
1488
1588
  rawApp.all(`${basePath}/*`, async (c) => {
1489
1589
  try {
1490
1590
  const response = await this.authManager.handleRequest(c.req.raw);