@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.js CHANGED
@@ -524,10 +524,56 @@ function buildDeviceAuthorizationPluginSchema() {
524
524
  }
525
525
 
526
526
  // src/auth-manager.ts
527
+ function isWebContainerRuntime() {
528
+ if (typeof globalThis === "undefined") return false;
529
+ const proc = globalThis.process;
530
+ return Boolean(proc?.versions?.webcontainer) || Boolean(proc?.env?.SHELL?.includes?.("jsh")) || Boolean(proc?.env?.STACKBLITZ);
531
+ }
532
+ var WebContainerRequestStateAsyncLocalStorage = class {
533
+ constructor() {
534
+ this.current = void 0;
535
+ }
536
+ run(store, fn) {
537
+ const prev = this.current;
538
+ this.current = store;
539
+ try {
540
+ const result = fn();
541
+ if (result && typeof result.then === "function") {
542
+ return result.finally(() => {
543
+ this.current = prev;
544
+ });
545
+ }
546
+ this.current = prev;
547
+ return result;
548
+ } catch (err) {
549
+ this.current = prev;
550
+ throw err;
551
+ }
552
+ }
553
+ getStore() {
554
+ return this.current;
555
+ }
556
+ };
557
+ function installWebContainerRequestStatePolyfill() {
558
+ if (!isWebContainerRuntime()) return;
559
+ const sym = /* @__PURE__ */ Symbol.for("better-auth:global");
560
+ const g = globalThis;
561
+ if (!g[sym]) {
562
+ g[sym] = { version: "0.0.0-polyfill", epoch: 0, context: {} };
563
+ }
564
+ if (!g[sym].context) g[sym].context = {};
565
+ if (!g[sym].context.requestStateAsyncStorage) {
566
+ g[sym].context.requestStateAsyncStorage = new WebContainerRequestStateAsyncLocalStorage();
567
+ console.warn(
568
+ "[AuthManager] WebContainer detected: installed synchronous request-state polyfill (node:async_hooks AsyncLocalStorage does not propagate context across await in WebContainer)."
569
+ );
570
+ }
571
+ }
527
572
  var AuthManager = class {
528
573
  constructor(config) {
529
574
  this.auth = null;
530
575
  this.config = config;
576
+ installWebContainerRequestStatePolyfill();
531
577
  if (config.authInstance) {
532
578
  this.auth = config.authInstance;
533
579
  }
@@ -744,8 +790,7 @@ var AuthManager = class {
744
790
  * the native (fast) hasher and never load `@noble/hashes`.
745
791
  */
746
792
  async resolvePasswordHasher() {
747
- const isWebContainer = typeof globalThis !== "undefined" && (Boolean(globalThis.process?.versions?.webcontainer) || Boolean(globalThis.process?.env?.SHELL?.includes?.("jsh")) || Boolean(globalThis.process?.env?.STACKBLITZ));
748
- if (!isWebContainer) return void 0;
793
+ if (!isWebContainerRuntime()) return void 0;
749
794
  try {
750
795
  const { scryptAsync } = await import("@noble/hashes/scrypt.js");
751
796
  const PARAMS = { N: 16384, r: 16, p: 1, dkLen: 64, maxmem: 128 * 16384 * 16 * 2 };
@@ -1530,6 +1575,61 @@ var AuthPlugin = class {
1530
1575
  return c.json({ success: false, error: { code: "internal", message: err.message } }, 500);
1531
1576
  }
1532
1577
  });
1578
+ rawApp.post(`${basePath}/admin/oauth2/toggle-disabled`, async (c) => {
1579
+ try {
1580
+ let body = {};
1581
+ try {
1582
+ body = await c.req.json();
1583
+ } catch {
1584
+ body = {};
1585
+ }
1586
+ const clientId = body?.client_id;
1587
+ const disabled = body?.disabled;
1588
+ if (typeof clientId !== "string" || clientId.length === 0) {
1589
+ return c.json({ success: false, error: { code: "invalid_request", message: "client_id is required" } }, 400);
1590
+ }
1591
+ if (typeof disabled !== "boolean") {
1592
+ return c.json({ success: false, error: { code: "invalid_request", message: "disabled must be a boolean" } }, 400);
1593
+ }
1594
+ const authApi = await this.authManager.getApi();
1595
+ const session = await authApi.getSession({ headers: c.req.raw.headers });
1596
+ if (!session?.user?.id) {
1597
+ return c.json({ success: false, error: { code: "unauthorized", message: "Sign in first" } }, 401);
1598
+ }
1599
+ if (session.user.role !== "admin") {
1600
+ return c.json({ success: false, error: { code: "forbidden", message: "Admin role required" } }, 403);
1601
+ }
1602
+ const dataEngine = this.authManager.getDataEngine();
1603
+ if (!dataEngine) {
1604
+ return c.json({ success: false, error: { code: "unavailable", message: "Data engine unavailable" } }, 503);
1605
+ }
1606
+ const existing = await dataEngine.findOne("sys_oauth_application", {
1607
+ where: { client_id: clientId }
1608
+ });
1609
+ if (!existing) {
1610
+ return c.json({ success: false, error: { code: "not_found", message: "OAuth client not found" } }, 404);
1611
+ }
1612
+ const updated = await dataEngine.update("sys_oauth_application", {
1613
+ id: existing.id,
1614
+ disabled,
1615
+ updated_at: new Date(Math.floor(Date.now() / 1e3) * 1e3)
1616
+ });
1617
+ if (!updated) {
1618
+ return c.json({ success: false, error: { code: "internal", message: "Unable to update OAuth client" } }, 500);
1619
+ }
1620
+ return c.json({
1621
+ success: true,
1622
+ data: {
1623
+ client_id: clientId,
1624
+ disabled
1625
+ }
1626
+ });
1627
+ } catch (error) {
1628
+ const err = error instanceof Error ? error : new Error(String(error));
1629
+ ctx.logger.error("[AuthPlugin] toggle-disabled failed", err);
1630
+ return c.json({ success: false, error: { code: "internal", message: err.message } }, 500);
1631
+ }
1632
+ });
1533
1633
  rawApp.all(`${basePath}/*`, async (c) => {
1534
1634
  try {
1535
1635
  const response = await this.authManager.handleRequest(c.req.raw);