@aooth/auth-moost 0.1.29 → 0.1.31

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.d.mts CHANGED
@@ -1879,6 +1879,28 @@ interface AuthWfCtx {
1879
1879
  interface AuthWorkflowOpts {
1880
1880
  autoLoginOnInvite?: boolean;
1881
1881
  autoLoginOnRecover?: boolean;
1882
+ /**
1883
+ * Closed universe of role ids the admin invite form may assign. NOT policy
1884
+ * (it does not vary per request) — it is static configuration, like `forms`.
1885
+ * The base `getAvailableRoles()` intersects this list with the CURRENT
1886
+ * inviter's ARBAC grants (`auth.invite` / `assign:<role>`) at request time,
1887
+ * so each inviter is offered — and server-side limited to — only the roles
1888
+ * they may actually delegate. If ARBAC is unreachable the list is used
1889
+ * verbatim (still a CLOSED whitelist, never fail-open).
1890
+ *
1891
+ * Leave unset to keep the legacy behaviour (NO whitelist — any role can be
1892
+ * assigned). When unset, `getAvailableRoles` is not overridden, and
1893
+ * `allowAnyInviteRole` is not set, a one-time warning fires the first time
1894
+ * the admin invite flow runs.
1895
+ */
1896
+ invitableRoles?: string[];
1897
+ /**
1898
+ * Acknowledge an intentionally-unrestricted invite form — silences the
1899
+ * "invite role whitelist is OFF" warning when `invitableRoles` is unset and
1900
+ * `getAvailableRoles` is not overridden. Records intent only; it does not by
1901
+ * itself relax or tighten enforcement. Default `false`.
1902
+ */
1903
+ allowAnyInviteRole?: boolean;
1882
1904
  /** Pincode infrastructure shared by login MFA, invite MFA, and recovery OTP. */
1883
1905
  mfa?: {
1884
1906
  pincodeLength?: number;
@@ -1952,6 +1974,8 @@ interface AuthWorkflowOpts {
1952
1974
  interface ResolvedAuthWorkflowOpts {
1953
1975
  autoLoginOnInvite: boolean;
1954
1976
  autoLoginOnRecover: boolean;
1977
+ invitableRoles: string[];
1978
+ allowAnyInviteRole: boolean;
1955
1979
  mfa: {
1956
1980
  pincodeLength: number;
1957
1981
  pincodeTtlMs: number;
@@ -2111,6 +2135,12 @@ declare class AuthWorkflow {
2111
2135
  protected readonly users: UserService;
2112
2136
  protected readonly auth: AuthCredential;
2113
2137
  protected readonly consentStore: ConsentStore;
2138
+ /**
2139
+ * Process-lifetime warn-once latch for the "invite role whitelist is OFF"
2140
+ * notice. App-level (singleton) state, NOT per-event — keeps the warning from
2141
+ * spamming on every invite while still surfacing the misconfig once.
2142
+ */
2143
+ private warnedOpenInviteWhitelist;
2114
2144
  constructor(opts: Partial<AuthWorkflowOpts>, users: UserService, auth: AuthCredential, consentStore: ConsentStore);
2115
2145
  /**
2116
2146
  * Unified outbound dispatch hook for direct synchronous deliveries
@@ -2174,12 +2204,39 @@ declare class AuthWorkflow {
2174
2204
  */
2175
2205
  protected afterMfaChanged(_ctx: AuthWfCtx): void | Promise<void>;
2176
2206
  /**
2177
- * Return the list of selectable role identifiers for the admin invite form.
2178
- * Mirrors the prior `InviteWorkflow.getAvailableRoles()` consumer hook —
2179
- * `undefined` (default) means no whitelist is enforced. Read by
2180
- * `prepareAvailableRoles`.
2207
+ * Selectable role ids for the admin invite form — ALSO enforced server-side
2208
+ * (`admin-form` rejects any submitted role outside this set). Read by
2209
+ * `prepareAvailableRoles`. Mirrors the prior `InviteWorkflow.getAvailableRoles()`
2210
+ * consumer hook.
2211
+ *
2212
+ * Default behaviour is driven by {@link AuthWorkflowOpts.invitableRoles}:
2213
+ * - **configured** → that universe intersected with the CURRENT inviter's
2214
+ * ARBAC grants (`auth.invite` / `assign:<role>`), so an inviter can only
2215
+ * delegate roles they may themselves assign. If ARBAC is unreachable the
2216
+ * universe is returned verbatim — still a CLOSED whitelist, never fail-open.
2217
+ * - **unset** → `undefined`, preserving the legacy "no whitelist" behaviour;
2218
+ * `prepareAvailableRoles` warns once unless
2219
+ * {@link AuthWorkflowOpts.allowAnyInviteRole} acknowledges it.
2220
+ *
2221
+ * Override for fully custom sourcing — the override then owns the gate
2222
+ * outright (no warning fires; `invitableRoles` is consulted only if the
2223
+ * override reads it).
2181
2224
  */
2182
2225
  protected getAvailableRoles(): Promise<string[] | undefined> | string[] | undefined;
2226
+ /**
2227
+ * Intersect a role universe with the current inviter's ARBAC grants — keep
2228
+ * only roles they hold `auth.invite` / `assign:<role>` for. Falls back to the
2229
+ * universe verbatim when ARBAC is unreachable (no event context / not wired),
2230
+ * which keeps the whitelist CLOSED rather than failing open.
2231
+ */
2232
+ protected filterInvitableRolesByArbac(universe: string[]): Promise<string[]>;
2233
+ /**
2234
+ * True when the admin invite form would assign roles with NO server-side
2235
+ * whitelist in effect: `invitableRoles` unset, `getAvailableRoles` not
2236
+ * overridden, and the open default not acknowledged via `allowAnyInviteRole`.
2237
+ * Drives the one-time `prepare-available-roles` warning.
2238
+ */
2239
+ protected inviteWhitelistIsOpen(): boolean;
2183
2240
  /**
2184
2241
  * Build the extras dict merged into the freshly-created user row. Runs for
2185
2242
  * EVERY new-account path: password-signup and invite-accept merge it at
@@ -2494,6 +2551,21 @@ declare class AuthWorkflow {
2494
2551
  * `AuthWorkflowOpts.autoLoginOnInvite` boolean (per §2 decision).
2495
2552
  */
2496
2553
  protected resolveAccept(_ctx: AuthWfCtx): NonNullable<AuthWfCtx["accept"]> | Promise<NonNullable<AuthWfCtx["accept"]>>;
2554
+ /**
2555
+ * Copy (heading + intro) for the unified set-password screen, staged by
2556
+ * `create-password-form` BEFORE the pause. Branches on the resolved
2557
+ * `ctx.password.changeReason` (`expired` / `reset`), then invite-accept
2558
+ * (`ctx.accept`), then the initial-password fallback. Override to re-brand any
2559
+ * phase; return a partial (`{ heading }` only) to change one field and leave
2560
+ * the other at whatever an earlier step staged, or `{}` to keep both as-is.
2561
+ */
2562
+ protected resolveSetPasswordCopy(ctx: AuthWfCtx): {
2563
+ heading?: string;
2564
+ intro?: string;
2565
+ } | Promise<{
2566
+ heading?: string;
2567
+ intro?: string;
2568
+ }>;
2497
2569
  /**
2498
2570
  * Resolve the recovery post-reset policy. Reached from recovery.flow.
2499
2571
  * `freshLoginRequired` REMOVED — the auto-login choice is the static
@@ -2920,11 +2992,25 @@ declare class AuthWorkflow {
2920
2992
  preparePasswordRules(ctx: AuthWfCtx): undefined | Promise<undefined>;
2921
2993
  preparePostReset(ctx: AuthWfCtx): undefined | Promise<undefined>;
2922
2994
  prepareRecoveryAltActions(ctx: AuthWfCtx): undefined | Promise<undefined>;
2995
+ /**
2996
+ * Roles the server will honor from the admin invite form. SECURITY boundary:
2997
+ * when `resolveAdminForm` returned `collectRoles: false` the role picker is
2998
+ * hidden, so any submitted `roles[]` is a crafted or buggy payload and is
2999
+ * IGNORED — roles in that mode come from `inferAdminRoles` (server-side),
3000
+ * never client input. This keeps role authorization independent of whether
3001
+ * `prepare-available-roles` ran: that step populates the `availableRoles`
3002
+ * whitelist the `admin-form` guard enforces against, but it is schema-gated on
3003
+ * `collectRoles`, so WITHOUT this check a `collectRoles:false` deployment
3004
+ * would let a crafted POST assign ANY role with no whitelist / per-role ARBAC
3005
+ * `assign:<role>` check.
3006
+ */
3007
+ protected effectiveInviteRoles(ctx: AuthWfCtx, submitted: string[]): string[];
2923
3008
  /**
2924
3009
  * Admin-side invite form. Pauses for `InviteForm`; binds `ctx.email` +
2925
3010
  * `ctx.admin.roles`. Server-side enforces the `availableRoles` whitelist
2926
- * (populated by `prepare-available-roles`). Calls `duplicateInviteCheck`
2927
- * to decide whether to reject duplicates.
3011
+ * (populated by `prepare-available-roles`) and, via {@link effectiveInviteRoles},
3012
+ * ignores any submitted roles when `resolveAdminForm` set `collectRoles:false`.
3013
+ * Calls `duplicateInviteCheck` to decide whether to reject duplicates.
2928
3014
  */
2929
3015
  adminForm(ctx: AuthWfCtx): Promise<unknown>;
2930
3016
  /**
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { C as Select2faForm, D as TermsBumpForm, E as StepUpConfirmForm, S as RemoveMfaConfirmForm, T as SignupForm, _ as PincodeForm, a as ConcurrencyLimitForm, c as EnrollConfirmForm, d as InviteForm, f as LoginCredentialsForm, g as PasswordReauthForm, h as MfaCodeForm, i as ChangePasswordForm, l as EnrollPickMethodForm, m as ManageMfaForm, n as AskPhoneForm, o as EmailIdentifierForm, r as AuthorizeConsentForm, s as EnrollAddressForm, t as AskEmailForm, u as EnrollTotpQrForm, v as ProveControlForm, w as SetPasswordForm, y as ProveControlOtpForm } from "./forms-xaBNc5Ng.mjs";
2
- import { Controller, HandlerPaths, Inherit, Inject, InjectMoostLogger, Injectable, Intercept, MoostInit, Optional, Param, Resolve, TInterceptorPriority, defineAfterInterceptor, defineBeforeInterceptor, getMoostMate, useControllerContext } from "moost";
2
+ import { Controller, HandlerPaths, Inherit, Inject, InjectMoostLogger, Injectable, Intercept, MoostInit, Optional, Param, Resolve, TInterceptorPriority, defineAfterInterceptor, defineBeforeInterceptor, getMoostMate, useControllerContext, useLogger } from "moost";
3
3
  import { AuthCredential, AuthError, generateMagicLinkToken } from "@aooth/auth";
4
4
  import { current, defineWook, eventTypeKey, key } from "@wooksjs/event-core";
5
5
  import { HttpError, useAuthorization, useCookies, useHeaders, useRequest, useResponse, useUrlParams } from "@wooksjs/event-http";
6
- import { ArbacAction, ArbacResource, getArbacMate } from "@aooth/arbac-moost";
6
+ import { ArbacAction, ArbacResource, getArbacMate, useArbac } from "@aooth/arbac-moost";
7
7
  import { FederatedIdentityStore, SEEN_DEVICES_DEFAULT_CAP, UserAuthError, UserService, generateMfaCode, generateTotpSecret, generateTotpUri, maskEmail, maskPhone, pickDefinedProfile, verifyTotpCode } from "@aooth/user";
8
8
  import { Body, Delete, Get, HttpError as HttpError$1, Post, Query } from "@moostjs/event-http";
9
9
  import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
@@ -942,6 +942,7 @@ const consentsPersistTailSchema = [{
942
942
  * is registerable as a Moost controller, but running any of its `@Workflow`
943
943
  * schemas would no-op every step.
944
944
  */
945
+ var _AuthWorkflow;
945
946
  /**
946
947
  * Default form schemas — the bundled `forms.as` models the workflow's
947
948
  * `useAtscriptWf()` callers resolve to. Consumers can override any field
@@ -988,6 +989,8 @@ function mergeAuthWorkflowOpts(opts) {
988
989
  return {
989
990
  autoLoginOnInvite: opts.autoLoginOnInvite ?? true,
990
991
  autoLoginOnRecover: opts.autoLoginOnRecover ?? false,
992
+ invitableRoles: opts.invitableRoles ?? [],
993
+ allowAnyInviteRole: opts.allowAnyInviteRole ?? false,
991
994
  mfa: {
992
995
  pincodeLength: opts.mfa?.pincodeLength ?? 6,
993
996
  pincodeTtlMs: opts.mfa?.pincodeTtlMs ?? 300 * 1e3,
@@ -1197,11 +1200,17 @@ function pickDefined(src, keys) {
1197
1200
  * so enumeration is moot there).
1198
1201
  */
1199
1202
  var RecoveryMethodUnavailableError = class extends Error {};
1200
- let AuthWorkflow = class AuthWorkflow {
1203
+ let AuthWorkflow = _AuthWorkflow = class AuthWorkflow {
1201
1204
  opts;
1202
1205
  users;
1203
1206
  auth;
1204
1207
  consentStore;
1208
+ /**
1209
+ * Process-lifetime warn-once latch for the "invite role whitelist is OFF"
1210
+ * notice. App-level (singleton) state, NOT per-event — keeps the warning from
1211
+ * spamming on every invite while still surfacing the misconfig once.
1212
+ */
1213
+ warnedOpenInviteWhitelist = false;
1205
1214
  constructor(opts, users, auth, consentStore) {
1206
1215
  this.opts = mergeAuthWorkflowOpts(opts);
1207
1216
  this.users = users;
@@ -1281,12 +1290,56 @@ let AuthWorkflow = class AuthWorkflow {
1281
1290
  */
1282
1291
  afterMfaChanged(_ctx) {}
1283
1292
  /**
1284
- * Return the list of selectable role identifiers for the admin invite form.
1285
- * Mirrors the prior `InviteWorkflow.getAvailableRoles()` consumer hook —
1286
- * `undefined` (default) means no whitelist is enforced. Read by
1287
- * `prepareAvailableRoles`.
1293
+ * Selectable role ids for the admin invite form — ALSO enforced server-side
1294
+ * (`admin-form` rejects any submitted role outside this set). Read by
1295
+ * `prepareAvailableRoles`. Mirrors the prior `InviteWorkflow.getAvailableRoles()`
1296
+ * consumer hook.
1297
+ *
1298
+ * Default behaviour is driven by {@link AuthWorkflowOpts.invitableRoles}:
1299
+ * - **configured** → that universe intersected with the CURRENT inviter's
1300
+ * ARBAC grants (`auth.invite` / `assign:<role>`), so an inviter can only
1301
+ * delegate roles they may themselves assign. If ARBAC is unreachable the
1302
+ * universe is returned verbatim — still a CLOSED whitelist, never fail-open.
1303
+ * - **unset** → `undefined`, preserving the legacy "no whitelist" behaviour;
1304
+ * `prepareAvailableRoles` warns once unless
1305
+ * {@link AuthWorkflowOpts.allowAnyInviteRole} acknowledges it.
1306
+ *
1307
+ * Override for fully custom sourcing — the override then owns the gate
1308
+ * outright (no warning fires; `invitableRoles` is consulted only if the
1309
+ * override reads it).
1310
+ */
1311
+ getAvailableRoles() {
1312
+ const universe = this.opts.invitableRoles;
1313
+ if (universe.length === 0) return void 0;
1314
+ return this.filterInvitableRolesByArbac(universe);
1315
+ }
1316
+ /**
1317
+ * Intersect a role universe with the current inviter's ARBAC grants — keep
1318
+ * only roles they hold `auth.invite` / `assign:<role>` for. Falls back to the
1319
+ * universe verbatim when ARBAC is unreachable (no event context / not wired),
1320
+ * which keeps the whitelist CLOSED rather than failing open.
1288
1321
  */
1289
- getAvailableRoles() {}
1322
+ async filterInvitableRolesByArbac(universe) {
1323
+ try {
1324
+ const arbac = useArbac();
1325
+ const verdicts = await Promise.all(universe.map((role) => arbac.evaluate({
1326
+ resource: "auth.invite",
1327
+ action: `assign:${role}`
1328
+ })));
1329
+ return universe.filter((_, i) => verdicts[i].allowed);
1330
+ } catch {
1331
+ return [...universe];
1332
+ }
1333
+ }
1334
+ /**
1335
+ * True when the admin invite form would assign roles with NO server-side
1336
+ * whitelist in effect: `invitableRoles` unset, `getAvailableRoles` not
1337
+ * overridden, and the open default not acknowledged via `allowAnyInviteRole`.
1338
+ * Drives the one-time `prepare-available-roles` warning.
1339
+ */
1340
+ inviteWhitelistIsOpen() {
1341
+ return !this.opts.allowAnyInviteRole && this.opts.invitableRoles.length === 0 && this.getAvailableRoles === _AuthWorkflow.prototype.getAvailableRoles;
1342
+ }
1290
1343
  /**
1291
1344
  * Build the extras dict merged into the freshly-created user row. Runs for
1292
1345
  * EVERY new-account path: password-signup and invite-accept merge it at
@@ -1728,6 +1781,33 @@ let AuthWorkflow = class AuthWorkflow {
1728
1781
  };
1729
1782
  }
1730
1783
  /**
1784
+ * Copy (heading + intro) for the unified set-password screen, staged by
1785
+ * `create-password-form` BEFORE the pause. Branches on the resolved
1786
+ * `ctx.password.changeReason` (`expired` / `reset`), then invite-accept
1787
+ * (`ctx.accept`), then the initial-password fallback. Override to re-brand any
1788
+ * phase; return a partial (`{ heading }` only) to change one field and leave
1789
+ * the other at whatever an earlier step staged, or `{}` to keep both as-is.
1790
+ */
1791
+ resolveSetPasswordCopy(ctx) {
1792
+ const reason = ctx.password?.changeReason;
1793
+ if (reason === "expired") return {
1794
+ heading: "Your password has expired",
1795
+ intro: "Choose a new password to continue. The previous one is no longer valid."
1796
+ };
1797
+ if (reason === "reset") return {
1798
+ heading: "Reset your password",
1799
+ intro: "Choose a new password for your account."
1800
+ };
1801
+ if (ctx.accept) return {
1802
+ heading: "Welcome — set your password",
1803
+ intro: "Choose a password to activate your account."
1804
+ };
1805
+ return {
1806
+ heading: "Set your initial password",
1807
+ intro: "Your account was created without a password. Choose one to continue."
1808
+ };
1809
+ }
1810
+ /**
1731
1811
  * Resolve the recovery post-reset policy. Reached from recovery.flow.
1732
1812
  * `freshLoginRequired` REMOVED — the auto-login choice is the static
1733
1813
  * `AuthWorkflowOpts.autoLoginOnRecover` boolean (per §2 decision).
@@ -2704,6 +2784,10 @@ let AuthWorkflow = class AuthWorkflow {
2704
2784
  async prepareAvailableRoles(ctx) {
2705
2785
  const roles = await this.getAvailableRoles();
2706
2786
  if (roles) (ctx.admin ??= {}).availableRoles = roles;
2787
+ else if (!this.warnedOpenInviteWhitelist && this.inviteWhitelistIsOpen()) {
2788
+ this.warnedOpenInviteWhitelist = true;
2789
+ useLogger("aooth:auth", current()).warn("Invite role whitelist is OFF — the admin invite form can assign ANY role, including privileged ones. Set `invitableRoles` (intersected with the inviter's ARBAC grants), override `getAvailableRoles()`, or set `allowAnyInviteRole: true` to acknowledge the open default.");
2790
+ }
2707
2791
  }
2708
2792
  /**
2709
2793
  * Merges policy from `resolveAccept` into `ctx.accept` (rather than
@@ -2736,16 +2820,33 @@ let AuthWorkflow = class AuthWorkflow {
2736
2820
  ctx.recoveryAltActions = result;
2737
2821
  }
2738
2822
  /**
2823
+ * Roles the server will honor from the admin invite form. SECURITY boundary:
2824
+ * when `resolveAdminForm` returned `collectRoles: false` the role picker is
2825
+ * hidden, so any submitted `roles[]` is a crafted or buggy payload and is
2826
+ * IGNORED — roles in that mode come from `inferAdminRoles` (server-side),
2827
+ * never client input. This keeps role authorization independent of whether
2828
+ * `prepare-available-roles` ran: that step populates the `availableRoles`
2829
+ * whitelist the `admin-form` guard enforces against, but it is schema-gated on
2830
+ * `collectRoles`, so WITHOUT this check a `collectRoles:false` deployment
2831
+ * would let a crafted POST assign ANY role with no whitelist / per-role ARBAC
2832
+ * `assign:<role>` check.
2833
+ */
2834
+ effectiveInviteRoles(ctx, submitted) {
2835
+ if (ctx.adminForm?.collectRoles === false) return [];
2836
+ return parseInviteRoles(submitted);
2837
+ }
2838
+ /**
2739
2839
  * Admin-side invite form. Pauses for `InviteForm`; binds `ctx.email` +
2740
2840
  * `ctx.admin.roles`. Server-side enforces the `availableRoles` whitelist
2741
- * (populated by `prepare-available-roles`). Calls `duplicateInviteCheck`
2742
- * to decide whether to reject duplicates.
2841
+ * (populated by `prepare-available-roles`) and, via {@link effectiveInviteRoles},
2842
+ * ignores any submitted roles when `resolveAdminForm` set `collectRoles:false`.
2843
+ * Calls `duplicateInviteCheck` to decide whether to reject duplicates.
2743
2844
  */
2744
2845
  async adminForm(ctx) {
2745
2846
  const wf = this.useAtscriptWfPublic(ctx, this.opts.forms.invite);
2746
2847
  const input = wf.resolveInput();
2747
2848
  const email = input.email;
2748
- const parsed = parseInviteRoles(input.roles);
2849
+ const parsed = this.effectiveInviteRoles(ctx, input.roles);
2749
2850
  if (Array.isArray(ctx.admin?.availableRoles)) {
2750
2851
  const allowed = new Set(ctx.admin.availableRoles);
2751
2852
  if (parsed.find((r) => !allowed.has(r)) !== void 0) throw this.throwPublic(ctx, wf, { errors: { roles: "Invalid role" } });
@@ -2926,19 +3027,9 @@ let AuthWorkflow = class AuthWorkflow {
2926
3027
  async createPasswordForm(ctx) {
2927
3028
  this.requireSubject(ctx);
2928
3029
  const password = ctx.password ??= {};
2929
- if (password.changeReason === "expired") {
2930
- password.heading = "Your password has expired";
2931
- password.intro = "Choose a new password to continue. The previous one is no longer valid.";
2932
- } else if (password.changeReason === "reset") {
2933
- password.heading = "Reset your password";
2934
- password.intro = "Choose a new password for your account.";
2935
- } else if (ctx.accept) {
2936
- password.heading = "Welcome — set your password";
2937
- password.intro = "Choose a password to activate your account.";
2938
- } else {
2939
- password.heading = "Set your initial password";
2940
- password.intro = "Your account was created without a password. Choose one to continue.";
2941
- }
3030
+ const copy = await this.resolveSetPasswordCopy(ctx);
3031
+ if (copy.heading !== void 0) password.heading = copy.heading;
3032
+ if (copy.intro !== void 0) password.intro = copy.intro;
2942
3033
  const wf = this.useAtscriptWfPublic(ctx, this.opts.forms.setPassword);
2943
3034
  let input;
2944
3035
  try {
@@ -6124,7 +6215,7 @@ __decorate([
6124
6215
  __decorateMetadata("design:paramtypes", []),
6125
6216
  __decorateMetadata("design:returntype", void 0)
6126
6217
  ], AuthWorkflow.prototype, "signupFlow", null);
6127
- AuthWorkflow = __decorate([
6218
+ AuthWorkflow = _AuthWorkflow = __decorate([
6128
6219
  Inherit(),
6129
6220
  Controller(),
6130
6221
  __decorateMetadata("design:paramtypes", [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aooth/auth-moost",
3
- "version": "0.1.29",
3
+ "version": "0.1.31",
4
4
  "description": "Moost auth integration for aoothjs — AuthGuard interceptor, useAuth composable, REST endpoints, workflows",
5
5
  "keywords": [
6
6
  "aoothjs",
@@ -57,18 +57,18 @@
57
57
  "access": "public"
58
58
  },
59
59
  "dependencies": {
60
- "@atscript/moost-wf": "^0.1.106",
60
+ "@atscript/moost-wf": "^0.1.107",
61
61
  "@wooksjs/http-body": "^0.7.19",
62
- "@aooth/arbac-moost": "^0.1.29",
63
- "@aooth/auth": "0.1.29",
64
- "@aooth/idp": "0.1.29",
65
- "@aooth/user": "0.1.29"
62
+ "@aooth/arbac-moost": "^0.1.31",
63
+ "@aooth/idp": "0.1.31",
64
+ "@aooth/auth": "0.1.31",
65
+ "@aooth/user": "0.1.31"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@atscript/core": "^0.1.78",
69
69
  "@atscript/typescript": "^0.1.78",
70
- "@atscript/ui": "^0.1.106",
71
- "@atscript/ui-fns": "^0.1.106",
70
+ "@atscript/ui": "^0.1.107",
71
+ "@atscript/ui-fns": "^0.1.107",
72
72
  "@moostjs/event-http": "^0.6.28",
73
73
  "@moostjs/event-wf": "^0.6.28",
74
74
  "moost": "^0.6.28",
@@ -76,7 +76,7 @@
76
76
  "wooks": "^0.7.19"
77
77
  },
78
78
  "peerDependencies": {
79
- "@atscript/moost-wf": "^0.1.106",
79
+ "@atscript/moost-wf": "^0.1.107",
80
80
  "@atscript/typescript": "^0.1.78",
81
81
  "@moostjs/event-http": "^0.6.28",
82
82
  "@moostjs/event-wf": "^0.6.28",