@jskit-ai/agent-docs 0.1.70 → 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 +7 -2
- 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 +13 -0
- package/reference/autogen/packages/auth-provider-local-db-core.md +56 -0
- package/reference/autogen/packages/auth-provider-supabase-core.md +0 -1
|
@@ -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
|
|
|
@@ -718,11 +718,16 @@ Inside the local provider, auth only projects provider identities into the app u
|
|
|
718
718
|
|
|
719
719
|
```js
|
|
720
720
|
const profileProjector = scope.has("auth.profile.projector")
|
|
721
|
-
?
|
|
721
|
+
? {
|
|
722
|
+
async syncIdentityProfile(profile, options = {}) {
|
|
723
|
+
const projector = scope.make("auth.profile.projector");
|
|
724
|
+
return projector.syncIdentityProfile(profile, options);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
722
727
|
: null;
|
|
723
728
|
```
|
|
724
729
|
|
|
725
|
-
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.
|
|
726
731
|
|
|
727
732
|
- The auth provider can authenticate users without an app database.
|
|
728
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,6 +62,16 @@ 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
77
|
- `createLocalAuthService({ backend, config, profileProjector = null, passwordStrategy = null, invitationContextResolver = null })`
|
|
@@ -96,6 +108,7 @@ Local functions
|
|
|
96
108
|
### `src/server/providers/AuthLocalServiceProvider.js`
|
|
97
109
|
Exports
|
|
98
110
|
- `AuthLocalServiceProvider`
|
|
111
|
+
- `resolveLocalBackendMode(scope)`
|
|
99
112
|
Local functions
|
|
100
113
|
- `parseBoolean(value, fallback = false)`
|
|
101
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
|