@isaijs/core 0.1.5 → 0.1.6

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.
@@ -1,3 +1,3 @@
1
1
  import { r as AuthTablesOptions } from "../data-layer-43pme0Gy.js";
2
- import { A as Permissions, F as Policy, I as Rules, L as StandardAction, M as Bound, N as DefinePolicy, P as Perms, a as OAuthMethod, c as Roles, i as Methods, j as AnyPolicy, l as SignInMethod, n as AuthConfig, o as Provider, r as AuthDefinition, s as RoleDefinition, t as Auth, u as createAuth } from "../index-D0FEnMhn.js";
2
+ import { A as Permissions, F as Policy, I as Rules, L as StandardAction, M as Bound, N as DefinePolicy, P as Perms, a as OAuthMethod, c as Roles, i as Methods, j as AnyPolicy, l as SignInMethod, n as AuthConfig, o as Provider, r as AuthDefinition, s as RoleDefinition, t as Auth, u as createAuth } from "../index-a7ElyL3B.js";
3
3
  export { type AnyPolicy, Auth, type AuthConfig, type AuthDefinition, type AuthTablesOptions, type Bound, type DefinePolicy, type Methods, type OAuthMethod, type Permissions, type Perms, Policy, type Provider, type RoleDefinition, type Roles, type Rules, type SignInMethod, type StandardAction, createAuth };
@@ -1,3 +1,3 @@
1
1
  import { t as Policy } from "../policies-KsqmlX67.js";
2
- import { a as createAuth, t as Auth } from "../create-auth-BHdX68Ng.js";
2
+ import { a as createAuth, t as Auth } from "../create-auth-BFKvQVOG.js";
3
3
  export { Auth, Policy, createAuth };
@@ -23,8 +23,8 @@ var Auth = class {
23
23
  perms = authPerms;
24
24
  /** The policies made with this instance's `policy()`. */
25
25
  policies = new PolicyRegistry();
26
- /** Set by the app's core when it starts: `invite` on its current database. */
27
- invites;
26
+ /** Set by the app's core when it starts: `invite` and `revoke` on its current database. */
27
+ people;
28
28
  constructor(define) {
29
29
  this.define = define;
30
30
  }
@@ -34,12 +34,20 @@ var Auth = class {
34
34
  * `held: "platform"` puts the assignment beyond the tenant's reach.
35
35
  */
36
36
  invite(input) {
37
- if (!this.invites) return Promise.reject(/* @__PURE__ */ new Error("isai: auth.invite is used before the runtime started the app"));
38
- return this.invites(input);
37
+ if (!this.people) return Promise.reject(/* @__PURE__ */ new Error("isai: auth.invite is used before the runtime started the app"));
38
+ return this.people.invite(input);
39
39
  }
40
- /** The core's: where `invite` writes. */
41
- attach(invites) {
42
- this.invites = invites;
40
+ /**
41
+ * Takes a role from `email`, from code (replacing a tenant's owner): its invite to the role is
42
+ * deleted, and the role taken away if it has an account in the current database. Safe to repeat.
43
+ */
44
+ revoke(input) {
45
+ if (!this.people) return Promise.reject(/* @__PURE__ */ new Error("isai: auth.revoke is used before the runtime started the app"));
46
+ return this.people.revoke(input);
47
+ }
48
+ /** The core's: where `invite` and `revoke` write. */
49
+ attach(people) {
50
+ this.people = people;
43
51
  }
44
52
  /** The config, for this env. Checked here for itself; against the databases by the core. */
45
53
  resolve(env) {
@@ -553,6 +553,11 @@ interface InviteInput {
553
553
  /** `"platform"`: the tenant's people can't take the role away. */
554
554
  readonly held?: (typeof HELD)[number];
555
555
  }
556
+ /** What `auth.revoke` takes: an email, and the key of a role from `app.ts`. */
557
+ interface RevokeInput {
558
+ readonly email: string;
559
+ readonly role: string;
560
+ }
556
561
  //#endregion
557
562
  //#region src/auth/create-auth.d.ts
558
563
  type Provider = (typeof PROVIDERS)[number];
@@ -600,6 +605,11 @@ interface AuthConfig {
600
605
  /** Every permission key: every policy's actions, and `auth.perms`. */
601
606
  permissionKeys(): readonly string[];
602
607
  }
608
+ /** `auth.invite` and `auth.revoke`, on the app's current database: the core's to attach. */
609
+ interface AuthPeople {
610
+ invite(input: InviteInput): Promise<void>;
611
+ revoke(input: RevokeInput): Promise<void>;
612
+ }
603
613
  declare class Auth<Env = unknown> {
604
614
  private readonly define;
605
615
  readonly perms: {
@@ -612,8 +622,8 @@ declare class Auth<Env = unknown> {
612
622
  };
613
623
  /** The policies made with this instance's `policy()`. */
614
624
  readonly policies: PolicyRegistry;
615
- /** Set by the app's core when it starts: `invite` on its current database. */
616
- private invites;
625
+ /** Set by the app's core when it starts: `invite` and `revoke` on its current database. */
626
+ private people;
617
627
  constructor(define: (env: Env) => AuthDefinition);
618
628
  /**
619
629
  * Gives `email` a role from `app.ts`, from code (a tenant's setup service, a seed): now, if it has
@@ -621,8 +631,13 @@ declare class Auth<Env = unknown> {
621
631
  * `held: "platform"` puts the assignment beyond the tenant's reach.
622
632
  */
623
633
  invite(input: InviteInput): Promise<void>;
624
- /** The core's: where `invite` writes. */
625
- attach(invites: (input: InviteInput) => Promise<void>): void;
634
+ /**
635
+ * Takes a role from `email`, from code (replacing a tenant's owner): its invite to the role is
636
+ * deleted, and the role taken away if it has an account in the current database. Safe to repeat.
637
+ */
638
+ revoke(input: RevokeInput): Promise<void>;
639
+ /** The core's: where `invite` and `revoke` write. */
640
+ attach(people: AuthPeople): void;
626
641
  /** The config, for this env. Checked here for itself; against the databases by the core. */
627
642
  resolve(env: Env): AuthConfig;
628
643
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { p as Runtime, t as AppCore } from "./index-Ce5p2-EB.js";
2
- import { C as Params, D as RouteHandler, E as RouteContext, O as RouteOptions, R as Rejected, S as Method, T as RouteBuilder, _ as CustomAction, b as AppConfig, d as NotImplementedError, f as AppModules, g as createApp, h as CreatedApp, k as User, m as AppOptions, p as App, v as Resource, w as Route, x as Named, y as ResourceOptions, z as fail } from "./index-D0FEnMhn.js";
2
+ import { C as Params, D as RouteHandler, E as RouteContext, O as RouteOptions, R as Rejected, S as Method, T as RouteBuilder, _ as CustomAction, b as AppConfig, d as NotImplementedError, f as AppModules, g as createApp, h as CreatedApp, k as User, m as AppOptions, p as App, v as Resource, w as Route, x as Named, y as ResourceOptions, z as fail } from "./index-a7ElyL3B.js";
3
3
  export { type App, type AppConfig, type AppCore, type AppModules, type AppOptions, type CreatedApp, type CustomAction, type Method, type Named, NotImplementedError, type Params, Rejected, type Resource, type ResourceOptions, Route, type RouteBuilder, type RouteContext, type RouteHandler, type RouteOptions, type Runtime, type User, createApp, fail };
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { n as notImplemented, t as NotImplementedError } from "./errors-mCNLlXg9
7
7
  import { t as PLATFORM_PREFIX } from "./tables-DgSwge7s.js";
8
8
  import { t as Seed } from "./seed-BObmdKdP.js";
9
9
  import { d as afterUpdate, f as bindFor, h as ownerFieldOf, m as isFalse, p as check, u as FALSE } from "./policies-KsqmlX67.js";
10
- import { i as checkRoles, n as authPerms, r as checkAuth } from "./create-auth-BHdX68Ng.js";
10
+ import { i as checkRoles, n as authPerms, r as checkAuth } from "./create-auth-BFKvQVOG.js";
11
11
  import { _ as permissionsOf, a as hashOf, b as syncRoles, c as GoogleError, f as verifyIdToken, g as safeReturn, h as redirect, i as clearedCookie, l as consentUrl, m as cookieOf, n as authModels, o as sessions, p as cookie, t as makers, u as exchangeCode, v as roleKeys, y as seedAs } from "./makers-P9kg68C8.js";
12
12
  import { t as WrongSize } from "./storage-body-7dWyMszh.js";
13
13
  import { RegExpRouter } from "hono/router/reg-exp-router";
@@ -2393,6 +2393,21 @@ async function invite(db, models, input) {
2393
2393
  }
2394
2394
  });
2395
2395
  }
2396
+ /**
2397
+ * `auth.revoke` from code, undoing `auth.invite`: the email's invite to the role is deleted, and if
2398
+ * it has an account here, the role is taken away (held by the platform or not). Its sessions stay,
2399
+ * with what its other roles allow. Safe to repeat. No permission or last-owner check: services are
2400
+ * trusted, so give the role to someone else first.
2401
+ */
2402
+ async function revoke(db, models, input) {
2403
+ const { User, Role, UserRole, Invite } = models;
2404
+ const role = await db.findOne(Role, { key: input.role });
2405
+ if (!role) throw new TypeError(`isai: auth.revoke takes the role "${input.role}", which app.ts's roles don't have`);
2406
+ const invite = await db.findOne(Invite, { email: input.email });
2407
+ if (invite?.role === role.id) await db.deleteOne(Invite, { id: invite.id });
2408
+ const user = await db.findOne(User, { email: input.email });
2409
+ if (user) await db.deleteMany(UserRole).where((h) => h.user.is(user.id)).where((h) => h.role.is(role.id));
2410
+ }
2396
2411
  //#endregion
2397
2412
  //#region src/auth/routes.ts
2398
2413
  /**
@@ -3139,7 +3154,10 @@ function createCore(config, env, options = {}) {
3139
3154
  checkRoles(auth, config.tenancy.roles, "tenancy.roles");
3140
3155
  }
3141
3156
  const models = auth ? authModels(auth.user) : void 0;
3142
- if (models) config.auth?.attach((input) => invite(currentDb(), models, input));
3157
+ if (models) config.auth?.attach({
3158
+ invite: (input) => invite(currentDb(), models, input),
3159
+ revoke: (input) => revoke(currentDb(), models, input)
3160
+ });
3143
3161
  const single = named.kind === "database" ? database({
3144
3162
  driver: named,
3145
3163
  name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isaijs/core",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "A batteries-included, type-safe TypeScript backend framework. Cloudflare first, no lock-in.",
5
5
  "type": "module",
6
6
  "license": "MIT",