@jskit-ai/agent-docs 0.1.69 → 0.1.71
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/guide/agent/app-setup/authentication.md +89 -3
- package/guide/agent/app-setup/database-layer.md +21 -11
- package/package.json +1 -1
- package/reference/autogen/README.md +1 -0
- package/reference/autogen/packages/auth-core.md +1 -0
- package/reference/autogen/packages/auth-provider-local-core.md +16 -2
- package/reference/autogen/packages/auth-provider-local-db-core.md +56 -0
- package/reference/autogen/packages/auth-provider-supabase-core.md +0 -1
- package/reference/autogen/packages/auth-web.md +3 -0
- package/reference/autogen/packages/users-core.md +4 -0
- package/reference/autogen/packages/workspaces-core.md +22 -1
- package/reference/autogen/packages/workspaces-web.md +15 -0
|
@@ -490,7 +490,7 @@ The first new place to inspect is `package.json`:
|
|
|
490
490
|
}
|
|
491
491
|
```
|
|
492
492
|
|
|
493
|
-
|
|
493
|
+
Four things are worth noticing immediately.
|
|
494
494
|
|
|
495
495
|
- `auth-core` owns the provider-neutral contract, shared actions, policy hooks, and capability normalization.
|
|
496
496
|
- `auth-provider-local-core` is the selected provider-specific runtime.
|
|
@@ -508,7 +508,91 @@ AUTH_LOCAL_BACKEND=file
|
|
|
508
508
|
|
|
509
509
|
The backend selection is intentionally local-provider-specific. `auth.local.backend` is the public server container token for replacing the file store later; Supabase and other external providers do not use it. A custom local backend must expose a single `withTransaction(callback)` method. JSKIT calls that method for register, login, recovery, password reset, profile update, session revocation, and security operations, and the callback receives transactional `users`, `sessions`, and `recovery` repositories.
|
|
510
510
|
|
|
511
|
-
The built-in file backend is for low-friction local development, first deploys with one persistent Node instance, and simple apps that accept that storage model. It writes `.jskit/auth/*.passwd` files behind a store-level lock. Do not treat it as horizontally scalable or serverless-safe storage; when the app needs replicated auth storage, register a custom `auth.local.backend
|
|
511
|
+
The built-in file backend is for low-friction local development, first deploys with one persistent Node instance, and simple apps that accept that storage model. It writes `.jskit/auth/*.passwd` files behind a store-level lock. Do not treat it as horizontally scalable or serverless-safe storage; when the app needs replicated auth storage, install the DB-backed local auth package or register a custom `auth.local.backend`.
|
|
512
|
+
|
|
513
|
+
That DB-backed local auth storage is not the same thing as the `users-core` profile tables. `users-core` creates app-owned `users` and `user_settings` rows later. DB-backed local auth stores the provider-owned auth state that the file backend would otherwise keep in `.jskit/auth/`.
|
|
514
|
+
|
|
515
|
+
The batteries-included DB package is `@jskit-ai/auth-provider-local-db-core`. It uses JSKIT's database runtime and owns three auth-local tables:
|
|
516
|
+
|
|
517
|
+
- `auth_local_users` for provider auth identities: normalized email, display name, disabled flag, password algorithm/version/salt/hash, and timestamps.
|
|
518
|
+
- `auth_local_sessions` for refresh sessions: session id, auth-local user id, refresh-token hash, session purpose such as `normal` or `recovery`, expiry, revocation, and timestamps.
|
|
519
|
+
- `auth_local_recovery` for password recovery: recovery token id, auth-local user id, recovery-token hash, expiry, used-at timestamp, and timestamps.
|
|
520
|
+
|
|
521
|
+
To use it, install a JSKIT database runtime and driver, install `auth-provider-local-db-core`, run migrations, and use `AUTH_LOCAL_BACKEND=db`. The package registers `auth.local.backend` for DB mode. If `AUTH_LOCAL_BACKEND=db` is set without the DB backend package, local auth fails instead of falling back to file storage.
|
|
522
|
+
|
|
523
|
+
**Summary: Adding Database-Backed Users**
|
|
524
|
+
|
|
525
|
+
There are two database-backed paths, and they solve different problems.
|
|
526
|
+
|
|
527
|
+
For normal app users and account settings, install the database runtime, install `users-web`, then run the migrations. That gives the app the `users` and `user_settings` tables through `users-core`, plus the `auth.profile.projector` bridge that projects a provider identity into a persistent JSKIT user profile.
|
|
528
|
+
|
|
529
|
+
For local auth credentials and sessions in SQL, keep `AUTH_PROVIDER=local`, install `auth-provider-local-db-core`, set `AUTH_LOCAL_BACKEND=db`, and run migrations. That package owns `auth_local_users`, `auth_local_sessions`, and `auth_local_recovery`, and registers the transactional `auth.local.backend` implementation.
|
|
530
|
+
|
|
531
|
+
The first path makes authenticated people real JSKIT users. The second path moves local auth's passwords, refresh sessions, and recovery tokens out of `.jskit/auth/` and into the database. Many apps need the first path before they need the second.
|
|
532
|
+
|
|
533
|
+
Apps that need audit logs, login counters, MFA records, or password history should add sidecar tables that reference `auth_local_users.id`; do not edit the package-owned auth-local migrations or add app-specific columns to those tables. Apps with different table names, external KMS, non-SQL storage, or unusual tenancy partitioning should replace the backend by registering their own `auth.local.backend`.
|
|
534
|
+
|
|
535
|
+
Local auth also applies the shared auth-service decorator registry from `auth-core`. Use that registry when an app or package needs to wrap provider behavior without owning the local auth tables. The local package exports a narrow helper for after-register work:
|
|
536
|
+
|
|
537
|
+
```js
|
|
538
|
+
import { registerAuthServiceDecorator } from "@jskit-ai/auth-core/server/authServiceDecoratorRegistry";
|
|
539
|
+
import { createLocalAuthRegisterHookDecorator } from "@jskit-ai/auth-provider-local-core/server/lib/index";
|
|
540
|
+
|
|
541
|
+
registerAuthServiceDecorator(app, "app.auth.local.permissions", (scope) => {
|
|
542
|
+
const permissionsService = scope.make("permissionsService");
|
|
543
|
+
|
|
544
|
+
return createLocalAuthRegisterHookDecorator({
|
|
545
|
+
decoratorId: "app.auth.local.permissions",
|
|
546
|
+
order: 10,
|
|
547
|
+
hook: {
|
|
548
|
+
hookId: "permissions",
|
|
549
|
+
blocking: true,
|
|
550
|
+
async handle({ actor, profile }) {
|
|
551
|
+
await permissionsService.createDefaultsForUser({
|
|
552
|
+
userId: actor.id,
|
|
553
|
+
email: actor.email,
|
|
554
|
+
displayName: profile.displayName
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
The hook must declare `blocking: true` or `blocking: false`. A blocking hook is awaited and its failure rejects the register call, which fits permission provisioning or other work the app needs before treating registration as complete. A non-blocking hook is scheduled after registration and logs failures, which fits audit logging or metrics. This helper runs after local auth registration and profile projection have succeeded; it does not share the local auth backend transaction. If the extension must be transaction-coupled with credential storage, wrap or replace `auth.local.backend` instead.
|
|
563
|
+
|
|
564
|
+
The local provider also has a separate password strategy seam. Use `auth.local.backend` to change where local auth records are stored. Use `auth.local.passwordStrategy` only when the app needs to change how passwords are hashed or verified, such as during a migration from an existing user table with existing password hashes.
|
|
565
|
+
|
|
566
|
+
Register `auth.local.passwordStrategy` before `AuthLocalServiceProvider` starts:
|
|
567
|
+
|
|
568
|
+
```js
|
|
569
|
+
import bcrypt from "bcryptjs";
|
|
570
|
+
import { verifyPassword as verifyScryptPassword } from "@jskit-ai/auth-provider-local-core/server/lib/index";
|
|
571
|
+
|
|
572
|
+
app.singleton("auth.local.passwordStrategy", () => ({
|
|
573
|
+
async verifyPassword(password, record) {
|
|
574
|
+
if (typeof record === "string" && /^\$2[aby]\$/.test(record)) {
|
|
575
|
+
return bcrypt.compare(password, record);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
return verifyScryptPassword(password, record);
|
|
579
|
+
}
|
|
580
|
+
}));
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
The strategy object can provide `hashPassword(password)`, `verifyPassword(password, storedPasswordRecord)`, or both. Missing methods fall back to the local provider's default scrypt implementation, so a migration verifier can accept old hashes while new registrations, resets, and password changes continue to write default JSKIT password records. JSKIT validates provided methods as functions and calls them with `this` bound to the strategy object.
|
|
584
|
+
|
|
585
|
+
Custom service callers can pass the same object directly:
|
|
586
|
+
|
|
587
|
+
```js
|
|
588
|
+
createLocalAuthService({
|
|
589
|
+
backend,
|
|
590
|
+
config,
|
|
591
|
+
passwordStrategy
|
|
592
|
+
});
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
JSKIT core does not install bcrypt or any legacy password dependency. If an app needs a legacy verifier, the app owns that dependency and keeps the backend as storage only.
|
|
512
596
|
|
|
513
597
|
If you later configure local SMTP password recovery, also set `APP_PUBLIC_URL` so reset links point back to the browser URL for this app.
|
|
514
598
|
|
|
@@ -680,7 +764,9 @@ For ordinary Vue component code there is usually no advantage to writing it this
|
|
|
680
764
|
|
|
681
765
|
The most important thing to understand is that the browser talks to **your app**, and the app talks to the **selected auth provider** through the provider-neutral `authService` contract.
|
|
682
766
|
|
|
683
|
-
With the local provider, the selected provider is in the same Node process. It verifies passwords, writes sessions, and stores local auth state through `auth.local.backend`. The default backend writes the `.jskit/auth/*.passwd` files;
|
|
767
|
+
With the local provider, the selected provider is in the same Node process. It verifies passwords, writes sessions, and stores local auth state through `auth.local.backend`. The default backend writes the `.jskit/auth/*.passwd` files; `auth-provider-local-db-core` moves that storage into package-owned database tables without changing the login UI or the shared auth routes.
|
|
768
|
+
|
|
769
|
+
If `users-core` or another package registers `auth.profile.projector`, local auth now resolves that projector lazily when it actually builds an auth payload for register, login, session refresh, or request authentication. That keeps local auth boot independent from the projector's own dependencies, such as repositories behind `internal.json-rest-api`.
|
|
684
770
|
|
|
685
771
|
That means there are two actors in the first-app flow:
|
|
686
772
|
|
|
@@ -58,9 +58,10 @@ The app gets three database scripts in `package.json`:
|
|
|
58
58
|
```json
|
|
59
59
|
{
|
|
60
60
|
"scripts": {
|
|
61
|
-
"db:
|
|
61
|
+
"db:migrations:sync": "jskit migrations changed",
|
|
62
|
+
"db:migrate": "npm run db:migrations:sync && knex --knexfile ./knexfile.js migrate:latest",
|
|
62
63
|
"db:migrate:rollback": "knex --knexfile ./knexfile.js migrate:rollback",
|
|
63
|
-
"db:migrate:status": "knex --knexfile ./knexfile.js migrate:list"
|
|
64
|
+
"db:migrate:status": "npm run db:migrations:sync && knex --knexfile ./knexfile.js migrate:list"
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
```
|
|
@@ -95,12 +96,14 @@ The app has two different migration-related layers:
|
|
|
95
96
|
|
|
96
97
|
Those are **not** the same step.
|
|
97
98
|
|
|
99
|
+
The npm scripts hide the easy-to-miss first step for normal use. `npm run db:migrate` and `npm run db:migrate:status` run `npm run db:migrations:sync` first, then run Knex. That means package upgrades can add new JSKIT-managed migration files before Knex checks what is pending.
|
|
100
|
+
|
|
98
101
|
### `jskit migrations ...` writes managed migration files
|
|
99
102
|
|
|
100
|
-
If you run:
|
|
103
|
+
If you run the sync script directly:
|
|
101
104
|
|
|
102
105
|
```bash
|
|
103
|
-
|
|
106
|
+
npm run db:migrations:sync
|
|
104
107
|
```
|
|
105
108
|
|
|
106
109
|
JSKIT checks the installed package state in `.jskit/lock.json` and materializes any managed migration files that need to exist in `migrations/`.
|
|
@@ -538,9 +541,10 @@ After installing the MySQL runtime, the important new pieces in `package.json` l
|
|
|
538
541
|
"mysql2": "^3.11.2"
|
|
539
542
|
},
|
|
540
543
|
"scripts": {
|
|
541
|
-
"db:
|
|
544
|
+
"db:migrations:sync": "jskit migrations changed",
|
|
545
|
+
"db:migrate": "npm run db:migrations:sync && knex --knexfile ./knexfile.js migrate:latest",
|
|
542
546
|
"db:migrate:rollback": "knex --knexfile ./knexfile.js migrate:rollback",
|
|
543
|
-
"db:migrate:status": "knex --knexfile ./knexfile.js migrate:list"
|
|
547
|
+
"db:migrate:status": "npm run db:migrations:sync && knex --knexfile ./knexfile.js migrate:list"
|
|
544
548
|
}
|
|
545
549
|
}
|
|
546
550
|
```
|
|
@@ -552,11 +556,12 @@ Those new dependencies divide into two roles:
|
|
|
552
556
|
- `knex` is the database toolkit used by both runtime code and migration commands
|
|
553
557
|
- `mysql2` is the actual Node driver that speaks to MySQL
|
|
554
558
|
|
|
555
|
-
The
|
|
559
|
+
The migration scripts are also worth reading carefully:
|
|
556
560
|
|
|
557
|
-
- `db:
|
|
561
|
+
- `db:migrations:sync` writes or refreshes JSKIT-managed migration files in `migrations/`
|
|
562
|
+
- `db:migrate` syncs JSKIT-managed migration files, then applies all pending Knex migrations
|
|
558
563
|
- `db:migrate:rollback` rolls back the last migration batch
|
|
559
|
-
- `db:migrate:status` lists applied and pending migrations
|
|
564
|
+
- `db:migrate:status` syncs JSKIT-managed migration files, then lists applied and pending migrations
|
|
560
565
|
|
|
561
566
|
They are not special JSKIT commands. They are ordinary project scripts, which makes them easy to run in any environment.
|
|
562
567
|
|
|
@@ -713,11 +718,16 @@ Inside the local provider, auth only projects provider identities into the app u
|
|
|
713
718
|
|
|
714
719
|
```js
|
|
715
720
|
const profileProjector = scope.has("auth.profile.projector")
|
|
716
|
-
?
|
|
721
|
+
? {
|
|
722
|
+
async syncIdentityProfile(profile, options = {}) {
|
|
723
|
+
const projector = scope.make("auth.profile.projector");
|
|
724
|
+
return projector.syncIdentityProfile(profile, options);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
717
727
|
: null;
|
|
718
728
|
```
|
|
719
729
|
|
|
720
|
-
That snippet explains the whole consequence of this chapter.
|
|
730
|
+
That snippet explains the whole consequence of this chapter. The provider checks whether the token exists, but it does not resolve the real projector until an auth payload actually needs profile projection.
|
|
721
731
|
|
|
722
732
|
- The auth provider can authenticate users without an app database.
|
|
723
733
|
- Nothing in `database-runtime-mysql` registers `auth.profile.projector`.
|
package/package.json
CHANGED
|
@@ -13,6 +13,7 @@ Startup navigation stays in `KERNEL_MAP.md`.
|
|
|
13
13
|
- [assistant-runtime](/packages/agent-docs/reference/autogen/packages/assistant-runtime.md)
|
|
14
14
|
- [auth-core](/packages/agent-docs/reference/autogen/packages/auth-core.md)
|
|
15
15
|
- [auth-provider-local-core](/packages/agent-docs/reference/autogen/packages/auth-provider-local-core.md)
|
|
16
|
+
- [auth-provider-local-db-core](/packages/agent-docs/reference/autogen/packages/auth-provider-local-db-core.md)
|
|
16
17
|
- [auth-provider-supabase-core](/packages/agent-docs/reference/autogen/packages/auth-provider-supabase-core.md)
|
|
17
18
|
- [auth-web](/packages/agent-docs/reference/autogen/packages/auth-web.md)
|
|
18
19
|
- [console-core](/packages/agent-docs/reference/autogen/packages/console-core.md)
|
|
@@ -65,6 +65,7 @@ Local functions
|
|
|
65
65
|
### `src/server/authServiceDecoratorRegistry.js`
|
|
66
66
|
Exports
|
|
67
67
|
- `AUTH_SERVICE_DECORATOR_TAG`
|
|
68
|
+
- `applyAuthServiceDecorators(scope, authService)`
|
|
68
69
|
- `registerAuthServiceDecorator(app, token, factory)`
|
|
69
70
|
- `resolveAuthServiceDecorators(scope)`
|
|
70
71
|
Local functions
|
|
@@ -47,6 +47,8 @@ Local functions
|
|
|
47
47
|
Exports
|
|
48
48
|
- `createLocalAuthService`
|
|
49
49
|
- `createLocalFileBackend`
|
|
50
|
+
- `LOCAL_AUTH_USER_REGISTERED_EVENT`
|
|
51
|
+
- `createLocalAuthRegisterHookDecorator`
|
|
50
52
|
- `hashPassword`
|
|
51
53
|
- `normalizePasswordStrategy`
|
|
52
54
|
- `verifyPassword`
|
|
@@ -60,9 +62,19 @@ Local functions
|
|
|
60
62
|
- `base64url(buffer)`
|
|
61
63
|
- `fromBase64url(value)`
|
|
62
64
|
|
|
65
|
+
### `src/server/lib/registerHookDecorator.js`
|
|
66
|
+
Exports
|
|
67
|
+
- `LOCAL_AUTH_USER_REGISTERED_EVENT`
|
|
68
|
+
- `createLocalAuthRegisterHookDecorator({ decoratorId = "auth.local.registerHook", order = 0, logger = null, hook = null } = {})`
|
|
69
|
+
Local functions
|
|
70
|
+
- `assertBlockingMode(hook)`
|
|
71
|
+
- `normalizeRegisterHook(hook = null)`
|
|
72
|
+
- `logNonBlockingHookFailure({ logger, hook, error } = {})`
|
|
73
|
+
- `runRegisterHook({ hook, result, logger })`
|
|
74
|
+
|
|
63
75
|
### `src/server/lib/service.js`
|
|
64
76
|
Exports
|
|
65
|
-
- `createLocalAuthService({ backend, config, profileProjector = null, passwordStrategy = null })`
|
|
77
|
+
- `createLocalAuthService({ backend, config, profileProjector = null, passwordStrategy = null, invitationContextResolver = null })`
|
|
66
78
|
Local functions
|
|
67
79
|
- `nowSeconds()`
|
|
68
80
|
- `isoFromNow(seconds)`
|
|
@@ -75,11 +87,12 @@ Local functions
|
|
|
75
87
|
- `clearCookieOptions(isProduction)`
|
|
76
88
|
- `buildProfile(user)`
|
|
77
89
|
- `buildActor(user, profile = null)`
|
|
78
|
-
- `buildAuthPayload({ user, session, profileProjector })`
|
|
90
|
+
- `buildAuthPayload({ user, session, profileProjector, profileOptions = {} })`
|
|
79
91
|
- `buildAccessToken({ user, session, secret, ttlSeconds = ACCESS_TTL_SECONDS })`
|
|
80
92
|
- `buildSessionPayload({ user, session, refreshToken, secret })`
|
|
81
93
|
- `validatePasswordInput(password)`
|
|
82
94
|
- `validateEmailInput(email)`
|
|
95
|
+
- `normalizeInvitationInput(value = null)`
|
|
83
96
|
- `maybeSendRecoveryEmail(config, recoveryUrl, email)`
|
|
84
97
|
|
|
85
98
|
### `src/server/lib/tokens.js`
|
|
@@ -95,6 +108,7 @@ Local functions
|
|
|
95
108
|
### `src/server/providers/AuthLocalServiceProvider.js`
|
|
96
109
|
Exports
|
|
97
110
|
- `AuthLocalServiceProvider`
|
|
111
|
+
- `resolveLocalBackendMode(scope)`
|
|
98
112
|
Local functions
|
|
99
113
|
- `parseBoolean(value, fallback = false)`
|
|
100
114
|
- `resolveRuntimeEnv(scope)`
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# packages/auth-provider-local-db-core
|
|
2
|
+
|
|
3
|
+
Generated by `npm run agent-docs:build`.
|
|
4
|
+
Do not edit manually.
|
|
5
|
+
|
|
6
|
+
Generated inventory for `packages/auth-provider-local-db-core`.
|
|
7
|
+
Use this on demand; do not load the full index at startup.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
- Source: `packages/auth-provider-local-db-core/**/*{.js,.mjs,.cjs,.vue}`
|
|
11
|
+
- Excludes: `test/`, `tests/`, `__tests__/`, `*.test.*`, `*.spec.*`, `*.vitest.*`, `node_modules/`, `dist/`, `coverage/`, `docs/`, `LEGACY/`, `.vitepress/cache/`, `.vitepress/dist/`
|
|
12
|
+
|
|
13
|
+
## Sections
|
|
14
|
+
|
|
15
|
+
### src
|
|
16
|
+
|
|
17
|
+
### `src/server/lib/dbBackend.js`
|
|
18
|
+
Exports
|
|
19
|
+
- `LOCAL_AUTH_DB_TABLES`
|
|
20
|
+
- `createLocalDbBackend({ knex, transactionManager } = {})`
|
|
21
|
+
Local functions
|
|
22
|
+
- `nowIso()`
|
|
23
|
+
- `toDate(value)`
|
|
24
|
+
- `requiredDateTime(value, fallback = nowIso())`
|
|
25
|
+
- `optionalDateTime(value)`
|
|
26
|
+
- `readDateTime(value, fallback = "")`
|
|
27
|
+
- `readPassword(row)`
|
|
28
|
+
- `writePassword(password = {})`
|
|
29
|
+
- `mapUser(row)`
|
|
30
|
+
- `mapSession(row)`
|
|
31
|
+
- `mapRecovery(row)`
|
|
32
|
+
- `userInsert(input = {})`
|
|
33
|
+
- `sessionInsert(input = {})`
|
|
34
|
+
- `recoveryInsert(input = {})`
|
|
35
|
+
- `assertBackendDependencies({ knex, transactionManager } = {})`
|
|
36
|
+
|
|
37
|
+
### `src/server/lib/index.js`
|
|
38
|
+
Exports
|
|
39
|
+
- `createLocalDbBackend`
|
|
40
|
+
- `LOCAL_AUTH_DB_TABLES`
|
|
41
|
+
|
|
42
|
+
### `src/server/providers/AuthLocalDbBackendServiceProvider.js`
|
|
43
|
+
Exports
|
|
44
|
+
- `AuthLocalDbBackendServiceProvider`
|
|
45
|
+
|
|
46
|
+
### templates
|
|
47
|
+
|
|
48
|
+
### `templates/migrations/auth_local_db_initial.cjs`
|
|
49
|
+
Exports
|
|
50
|
+
- None
|
|
51
|
+
|
|
52
|
+
### root
|
|
53
|
+
|
|
54
|
+
### `package.descriptor.mjs`
|
|
55
|
+
Exports
|
|
56
|
+
- None
|
|
@@ -56,6 +56,9 @@ Exports
|
|
|
56
56
|
### `src/client/composables/loginView/useLoginViewState.js`
|
|
57
57
|
Exports
|
|
58
58
|
- `useLoginViewState({ placementContext } = {})`
|
|
59
|
+
Local functions
|
|
60
|
+
- `readWindowSearchParam(name = "")`
|
|
61
|
+
- `resolveInitialMode()`
|
|
59
62
|
|
|
60
63
|
### `src/client/composables/loginView/useLoginViewValidation.js`
|
|
61
64
|
Exports
|
|
@@ -207,11 +207,26 @@ Exports
|
|
|
207
207
|
Local functions
|
|
208
208
|
- `resolveWorkspaceAggregateRecordId(record = {}, context = {})`
|
|
209
209
|
|
|
210
|
+
### `src/server/workspaceMembers/defaultWorkspaceInviteEmail.js`
|
|
211
|
+
Exports
|
|
212
|
+
- `renderDefaultWorkspaceInviteEmail({ inviteUrl = "", workspace = {}, inviter = null, roleSid = "member", expiresAt = "" } = {})`
|
|
213
|
+
Local functions
|
|
214
|
+
- `escapeHtml(value = "")`
|
|
215
|
+
|
|
210
216
|
### `src/server/workspaceMembers/registerWorkspaceMembers.js`
|
|
211
217
|
Exports
|
|
212
218
|
- `registerWorkspaceMembers(app)`
|
|
213
219
|
Local functions
|
|
214
220
|
- `resolveWorkspaceMembersInviteExpiresInMs(appConfig = {})`
|
|
221
|
+
- `resolveWorkspaceInviteEmailTemplate(scope, appConfig = {})`
|
|
222
|
+
|
|
223
|
+
### `src/server/workspaceMembers/workspaceInviteUrls.js`
|
|
224
|
+
Exports
|
|
225
|
+
- `buildInvitePath(token, pathTemplate = "/invite/:token")`
|
|
226
|
+
- `createWorkspaceInviteUrlBuilder({ appConfig = {}, env = {} } = {})`
|
|
227
|
+
Local functions
|
|
228
|
+
- `normalizeInvitePathTemplate(value = "")`
|
|
229
|
+
- `normalizeBaseUrl(value = "")`
|
|
215
230
|
|
|
216
231
|
### `src/server/workspaceMembers/workspaceMembersActions.js`
|
|
217
232
|
Exports
|
|
@@ -219,13 +234,14 @@ Exports
|
|
|
219
234
|
|
|
220
235
|
### `src/server/workspaceMembers/workspaceMembersService.js`
|
|
221
236
|
Exports
|
|
222
|
-
- `createService({ workspaceMembershipsRepository, workspaceInvitesRepository, inviteExpiresInMs, roleCatalog = null, workspaceInvitationsEnabled = true } = {})`
|
|
237
|
+
- `createService({ workspaceMembershipsRepository, workspaceInvitesRepository, inviteExpiresInMs, roleCatalog = null, workspaceInvitationsEnabled = true, inviteUrlBuilder = null, workspaceInviteMailer = null, workspaceInviteEmailTemplate = renderDefaultWorkspaceInviteEmail } = {})`
|
|
223
238
|
|
|
224
239
|
### `src/server/workspacePendingInvitations/bootWorkspacePendingInvitations.js`
|
|
225
240
|
Exports
|
|
226
241
|
- `bootWorkspacePendingInvitations(app)`
|
|
227
242
|
Local functions
|
|
228
243
|
- `resolveAuthenticatedUserRecordId(_record, context = {})`
|
|
244
|
+
- `resolveInviteResolutionRecordId(record = {})`
|
|
229
245
|
|
|
230
246
|
### `src/server/workspacePendingInvitations/registerWorkspacePendingInvitations.js`
|
|
231
247
|
Exports
|
|
@@ -287,6 +303,7 @@ Exports
|
|
|
287
303
|
- `WORKSPACE_INVITES_TRANSPORT`
|
|
288
304
|
- `WORKSPACE_INVITE_CREATE_TRANSPORT`
|
|
289
305
|
- `WORKSPACE_INVITE_REDEEM_TRANSPORT`
|
|
306
|
+
- `WORKSPACE_INVITATION_RESOLVE_TRANSPORT`
|
|
290
307
|
- `WORKSPACE_PENDING_INVITATIONS_TRANSPORT`
|
|
291
308
|
|
|
292
309
|
### `src/shared/operationMessages.js`
|
|
@@ -427,6 +444,10 @@ Local functions
|
|
|
427
444
|
- `hasColumn(knex, tableName, columnName)`
|
|
428
445
|
- `normalizeHexColor(value)`
|
|
429
446
|
|
|
447
|
+
### `templates/packages/main/src/server/email/workspaceInviteEmail.js`
|
|
448
|
+
Exports
|
|
449
|
+
- `renderWorkspaceInviteEmail({ inviteUrl = "", workspace = {}, inviter = null, roleSid = "member", expiresAt = "" } = {})`
|
|
450
|
+
|
|
430
451
|
### root
|
|
431
452
|
|
|
432
453
|
### `package.descriptor.mjs`
|
|
@@ -39,6 +39,7 @@ Local functions
|
|
|
39
39
|
- `isRevokeInviteLoading(inviteId)`
|
|
40
40
|
- `isRemoveMemberLoading(memberUserId)`
|
|
41
41
|
- `onSubmitInvite()`
|
|
42
|
+
- `onCopyInviteLink()`
|
|
42
43
|
- `onRevokeInvite(inviteId)`
|
|
43
44
|
- `onMemberRoleUpdate(member, roleSid)`
|
|
44
45
|
- `onRemoveMember(member)`
|
|
@@ -73,6 +74,14 @@ Exports
|
|
|
73
74
|
Exports
|
|
74
75
|
- None
|
|
75
76
|
|
|
77
|
+
### `src/client/components/WorkspaceInviteLanding.vue`
|
|
78
|
+
Exports
|
|
79
|
+
- None
|
|
80
|
+
Local functions
|
|
81
|
+
- `buildAuthUrl(mode)`
|
|
82
|
+
- `refreshInvite()`
|
|
83
|
+
- `acceptInvite()`
|
|
84
|
+
|
|
76
85
|
### `src/client/components/WorkspaceMembersClientElement.vue`
|
|
77
86
|
Exports
|
|
78
87
|
- None
|
|
@@ -91,6 +100,7 @@ Local functions
|
|
|
91
100
|
- `applyWorkspaceSettingsPolicy(payload = {})`
|
|
92
101
|
- `refreshLoad()`
|
|
93
102
|
- `submitInvite()`
|
|
103
|
+
- `copyCreatedInviteLink()`
|
|
94
104
|
- `submitRevokeInvite(inviteId)`
|
|
95
105
|
- `submitMemberRoleUpdate(member, roleSid)`
|
|
96
106
|
- `submitRemoveMember(member)`
|
|
@@ -125,6 +135,7 @@ Local functions
|
|
|
125
135
|
Exports
|
|
126
136
|
- `WorkspacesWebClientProvider`
|
|
127
137
|
- `WorkspaceMembersClientElement`
|
|
138
|
+
- `WorkspaceInviteLanding`
|
|
128
139
|
- `clientProviders`
|
|
129
140
|
|
|
130
141
|
### `src/client/lib/bootstrap.js`
|
|
@@ -335,6 +346,10 @@ Exports
|
|
|
335
346
|
Exports
|
|
336
347
|
- None
|
|
337
348
|
|
|
349
|
+
### `templates/src/pages/invite/[token].vue`
|
|
350
|
+
Exports
|
|
351
|
+
- None
|
|
352
|
+
|
|
338
353
|
### `templates/src/surfaces/admin/index.vue`
|
|
339
354
|
Exports
|
|
340
355
|
- None
|