@starci/hfs 5.1.0 → 5.2.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/CHANGELOG.md +20 -0
- package/README.md +10 -1
- package/db/postgres.mjs +9 -1
- package/package.json +1 -1
- package/runtime/knowledge/hfs/canon-pins.yaml +30 -9
- package/runtime/knowledge/hfs/fe-stack.yaml +7 -7
- package/runtime/knowledge/hfs/fork-images.yaml +7 -0
- package/runtime/knowledge/hfs/rules.yaml +55 -7
- package/runtime/knowledge/hfs/slots.yaml +75 -24
- package/runtime/modules/kernel/failure-codes.yaml +62 -0
- package/runtime/modules/schemas/application-stacks.schema.yaml +6 -0
- package/runtime/scripts/hfs/architecture/identity.mjs +18 -83
- package/runtime/scripts/hfs/architecture/transport-owner.d.mts +1 -2
- package/runtime/scripts/hfs/architecture/transport-owner.mjs +3 -6
- package/runtime/scripts/hfs/manifest-shape.d.mts +1 -0
- package/runtime/scripts/hfs/manifest-shape.mjs +3 -1
- package/runtime/scripts/hfs/rules/a15-findings.mjs +5 -0
- package/runtime/scripts/hfs/rules/stacks-local.d.mts +7 -0
- package/runtime/scripts/hfs/rules/stacks-local.mjs +71 -0
- package/runtime/scripts/hfs/rules/stacks-runtime.mjs +6 -1
- package/runtime/scripts/hfs/rules/stacks-service-images.d.mts +12 -0
- package/runtime/scripts/hfs/rules/stacks-service-images.mjs +120 -0
- package/runtime/scripts/hfs/secret-dev-init.d.mts +11 -0
- package/runtime/scripts/hfs/secret-dev-init.mjs +79 -0
- package/runtime/scripts/hfs/secret.mjs +10 -7
- package/runtime/scripts/hfs/slots.mjs +1 -1
- package/runtime/scripts/hfs/stack-local-config.d.mts +101 -0
- package/runtime/scripts/hfs/stack-local-config.mjs +320 -0
- package/runtime/scripts/hfs/stacks-gate.mjs +1 -1
- package/runtime/scripts/lib/swarm-stack.d.mts +2 -1
- package/runtime/scripts/lib/swarm-stack.mjs +2 -2
- package/scaffold/add-module.d.mts +16 -0
- package/scaffold/add-module.mjs +232 -0
- package/scaffold/add-queue-lite.mjs +49 -0
- package/scaffold/add.mjs +5 -0
- package/scaffold/app.mjs +7 -7
- package/scaffold/module-registry.d.mts +19 -0
- package/scaffold/module-registry.mjs +84 -0
- package/src/main.mjs +23 -2
- package/stack/cli.mjs +6 -1
- package/stack/context.d.mts +15 -0
- package/stack/context.mjs +1 -0
- package/stack/local-cli.d.mts +25 -0
- package/stack/local-cli.mjs +89 -0
- package/stack/local-config.d.mts +17 -0
- package/stack/local-config.mjs +37 -0
- package/stack/local-custody.d.mts +24 -0
- package/stack/local-custody.mjs +109 -0
- package/stack/local-doctor.d.mts +6 -0
- package/stack/local-doctor.mjs +49 -0
- package/stack/local-down.d.mts +8 -0
- package/stack/local-down.mjs +20 -0
- package/stack/local-host.d.mts +42 -0
- package/stack/local-host.mjs +163 -0
- package/stack/local-logs.d.mts +8 -0
- package/stack/local-logs.mjs +32 -0
- package/stack/local-ports.d.mts +7 -0
- package/stack/local-ports.mjs +39 -0
- package/stack/local-prepare.d.mts +22 -0
- package/stack/local-prepare.mjs +62 -0
- package/stack/local-run.d.mts +71 -0
- package/stack/local-run.mjs +200 -0
- package/stack/local-state.d.mts +35 -0
- package/stack/local-state.mjs +29 -0
- package/stack/local-status.d.mts +6 -0
- package/stack/local-status.mjs +36 -0
- package/stack/local-up.d.mts +11 -0
- package/stack/local-up.mjs +166 -0
- package/stack/local-verify.d.mts +6 -0
- package/stack/local-verify.mjs +21 -0
- package/sync/index.d.mts +13 -12
- package/sync/index.mjs +83 -28
- package/templates/app/module/jest.config.js.tpl +8 -0
- package/templates/app/module/src/index.ts.tpl +2 -0
- package/templates/app/module/src/manifest/declaration.spec.ts.tpl +11 -0
- package/templates/app/module/src/manifest/declaration.ts.tpl +13 -0
- package/templates/app/module/src/manifest/index.ts.tpl +1 -0
- package/templates/app/module/src/public/index.ts.tpl +2 -0
- package/templates/app/module/src/template/__name__.template.spec.ts.tpl +13 -0
- package/templates/app/module/src/template/__name__.template.ts.tpl +41 -0
- package/templates/app/module/src/template/index.ts.tpl +1 -0
- package/templates/app/module/src/workbench/components/__pascal__WorkbenchView.tsx.tpl +16 -0
- package/templates/app/module/src/workbench/index.ts.tpl +2 -0
- package/templates/app/package-scripts/package.json +1 -1
- package/templates/app/package-scripts-lite/package.json +1 -1
- package/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml +76 -70
- package/templates/app/skeleton-lite/.starcistacks/dev/README.md +23 -13
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/compose/compose.yaml +25 -0
- package/templates/app/skeleton-lite/.starcistacks/dev/runtime/env/KEYS.md +18 -26
- package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/stack.yaml +1 -0
- package/templates/app/skeleton-lite/.starcistacks/production/runtime/env/KEYS.md +2 -1
- package/templates/app/skeleton-lite/db/migrations/__timestamp___baseline.sql +57 -14
- package/templates/be/auth-lite/src/features/api/auth/application/auth.contracts.ts +11 -0
- package/templates/be/auth-lite/src/features/api/auth/application/get-jwks.handler.ts +23 -0
- package/templates/be/auth-lite/src/features/api/auth/application/get-jwks.query.ts +12 -0
- package/templates/be/auth-lite/src/features/api/auth/application/google-begin.command.ts +11 -0
- package/templates/be/auth-lite/src/features/api/auth/application/google-begin.handler.ts +22 -0
- package/templates/be/auth-lite/src/features/api/auth/application/google-complete.command.ts +12 -0
- package/templates/be/auth-lite/src/features/api/auth/application/google-complete.handler.ts +23 -0
- package/templates/be/auth-lite/src/features/api/auth/application/login.command.ts +12 -0
- package/templates/be/auth-lite/src/features/api/auth/application/login.handler.ts +23 -0
- package/templates/be/auth-lite/src/features/api/auth/application/logout.command.ts +11 -0
- package/templates/be/auth-lite/src/features/api/auth/application/logout.handler.ts +22 -0
- package/templates/be/auth-lite/src/features/api/auth/application/refresh.command.ts +12 -0
- package/templates/be/auth-lite/src/features/api/auth/application/refresh.handler.ts +23 -0
- package/templates/be/auth-lite/src/features/api/auth/application/session.command.ts +12 -0
- package/templates/be/auth-lite/src/features/api/auth/application/session.handler.ts +23 -0
- package/templates/be/auth-lite/src/features/api/auth/auth.module-definition.ts +13 -0
- package/templates/be/auth-lite/src/features/api/auth/auth.module.ts +16 -0
- package/templates/be/auth-lite/src/features/api/auth/auth.options.ts +3 -0
- package/templates/be/auth-lite/src/features/api/auth/index.ts +2 -0
- package/templates/be/auth-lite/src/features/api/auth/transport/http/auth-http.module-definition.ts +13 -0
- package/templates/be/auth-lite/src/features/api/auth/transport/http/auth-http.module.ts +9 -0
- package/templates/be/auth-lite/src/features/api/auth/transport/http/auth-http.options.ts +3 -0
- package/templates/be/auth-lite/src/features/api/auth/transport/http/auth.controller.ts +90 -0
- package/templates/be/auth-lite/src/features/api/auth/transport/http/dto/google-start.request.ts +17 -0
- package/templates/be/auth-lite/src/features/api/auth/transport/http/dto/login.request.ts +16 -0
- package/templates/be/auth-lite/src/modules/domain/identity/account-directory.service.spec.ts +46 -0
- package/templates/be/auth-lite/src/modules/domain/identity/account-directory.service.ts +28 -0
- package/templates/be/auth-lite/src/modules/domain/identity/authenticator.service.spec.ts +145 -0
- package/templates/be/auth-lite/src/modules/domain/identity/authenticator.service.ts +95 -0
- package/templates/be/auth-lite/src/modules/domain/identity/persistence/entities/auth-identity.entity.ts +38 -0
- package/templates/be/auth-lite/src/modules/domain/identity/persistence/entities/auth-user.entity.ts +54 -0
- package/templates/be/auth-lite/src/modules/domain/identity/persistence/entities/identity-attempt.entity.ts +18 -0
- package/templates/be/auth-lite/src/modules/domain/identity/persistence/entities/identity-refresh-token.entity.ts +34 -0
- package/templates/be/auth-lite/src/modules/domain/identity/persistence/entities/identity-session.entity.ts +30 -0
- package/templates/be/auth-lite/src/modules/domain/identity/persistence/entities/index.ts +17 -0
- package/templates/be/auth-lite/src/modules/domain/identity/rate-counter.service.spec.ts +86 -0
- package/templates/be/auth-lite/src/modules/domain/identity/rate-counter.service.ts +45 -0
- package/templates/be/auth-lite/src/modules/domain/identity/session-store.service.spec.ts +97 -0
- package/templates/be/auth-lite/src/modules/domain/identity/session-store.service.ts +81 -0
- package/templates/be/auth-lite/src/modules/domain/identity/sign-in.service.spec.ts +78 -0
- package/templates/be/auth-lite/src/modules/domain/identity/sign-in.service.ts +87 -0
- package/templates/be/auth-lite/src/tests/fixtures/builders/identity.builder.ts +44 -0
- package/templates/be/skeleton-lite/apps/api/src/app.module.ts +6 -5
- package/templates/be/skeleton-lite/apps/api/src/compose/api.ts +3 -2
- package/templates/be/skeleton-lite/apps/api/src/compose/integrations.ts +10 -5
- package/templates/be/skeleton-lite/src/modules/domain/identity/errors/identity.error.ts +34 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.decorators.ts +22 -1
- package/templates/be/skeleton-lite/src/modules/domain/identity/identity.module.ts +47 -2
- package/templates/be/skeleton-lite/src/modules/domain/identity/index.ts +2 -0
- package/templates/be/skeleton-lite/src/modules/domain/identity/messages/identity.messages.ts +24 -0
- package/templates/be/skeleton-lite/src/modules/integrations/object-storage/index.ts +3 -3
- package/templates/be/skeleton-lite/src/modules/integrations/object-storage/object-storage.config.ts +3 -1
- package/templates/be/skeleton-lite/src/modules/integrations/object-storage/object-storage.decorators.ts +8 -4
- package/templates/be/skeleton-lite/src/modules/integrations/object-storage/object-storage.module-definition.ts +12 -0
- package/templates/be/skeleton-lite/src/modules/integrations/object-storage/object-storage.module.ts +29 -0
- package/templates/be/skeleton-lite/src/modules/integrations/object-storage/object-storage.options.ts +6 -31
- package/templates/be/skeleton-lite/src/modules/integrations/passport/errors/passport.error.ts +18 -9
- package/templates/be/skeleton-lite/src/modules/integrations/passport/index.ts +35 -11
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.config.spec.ts +44 -8
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.config.ts +40 -18
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.decorators.ts +18 -6
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.kit.spec.ts +73 -0
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.kit.ts +26 -0
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.options.ts +24 -53
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.registration.ts +31 -0
- package/templates/be/skeleton-lite/src/modules/platform/cqrs/index.ts +1 -1
- package/templates/be/skeleton-lite/src/modules/platform/database/entities.ts +2 -1
- package/templates/be/skeleton-lite/src/modules/platform/http-security/index.ts +1 -1
- package/templates/be/skeleton-lite/src/tests/fixtures/builders/api.builder.ts +11 -4
- package/templates/be/test-world/e2e/serves-once-migrated.e2e-spec.ts.tpl +9 -9
- package/templates/be/test-world/fixtures/migrations.sql.ts.tpl +4 -4
- package/templates/fe/auth-lite/apps/web/src/modules/auth/client.ts +26 -0
- package/templates/fe/common/site-shell.tsx.partial +3 -3
- package/templates/fe/skeleton/apps/__app__/src/components/providers/AppProviders/index.tsx +33 -10
- package/templates/fe/skeleton/apps/__app__/src/hooks/auth/index.ts +1 -0
- package/templates/fe/skeleton/apps/__app__/src/hooks/auth/useViewerId.ts +11 -0
- package/templates/fe/skeleton/apps/__app__/src/modules/toast/toast.tsx +15 -12
- package/templates/fe/skeleton/apps/__app__/src/modules/viewer-cache/index.ts +5 -0
- package/templates/fe/skeleton/apps/__app__/src/redux/slices/session.ts +1 -1
- package/templates/fe/skeleton/packages/__project__-i18n/src/index.ts +1 -1
- package/templates/fe/skeleton/packages/__project__-ui/src/composites/NotFoundNotice/index.tsx +4 -7
- package/templates/fe/skeleton/packages/__project__-ui/src/frames/SiteShell/index.tsx +2 -3
- package/templates/fe/skeleton-lite/apps/web/src/components/composites/NotFoundNotice/index.tsx +4 -7
- package/templates/fe/skeleton-lite/apps/web/src/components/frames/SiteShell/index.tsx +1 -2
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/Caddyfile +0 -16
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/owner-actions.md +0 -11
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/recovery/restore-proof.md +0 -7
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/releases/current.yaml +0 -6
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/releases/images.lock.yaml +0 -8
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/releases/previous.yaml +0 -6
- package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/stack.yaml +0 -186
- package/templates/be/skeleton-lite/src/modules/integrations/object-storage/object-storage.client.spec.ts +0 -22
- package/templates/be/skeleton-lite/src/modules/integrations/object-storage/object-storage.client.ts +0 -25
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.cookie.spec.ts +0 -104
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.cookie.ts +0 -34
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.password.spec.ts +0 -28
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.password.ts +0 -11
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.tokens.spec.ts +0 -88
- package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.tokens.ts +0 -69
- package/templates/be/skeleton-lite/src/modules/integrations/passport/strategies/google.strategy.ts +0 -41
- package/templates/be/skeleton-lite/src/modules/integrations/passport/strategies/local.strategy.ts +0 -40
- package/templates/be/skeleton-lite/src/modules/integrations/passport/strategies/oauth-state.store.ts +0 -63
- package/templates/fe/skeleton/packages/__project__-ui/src/frames/SiteShell/classNames.ts +0 -4
- package/templates/fe/skeleton-lite/apps/__app__/src/modules/auth/auth-door.ts +0 -30
- package/templates/fe/skeleton-lite/apps/__app__/src/modules/auth/client.ts +0 -50
- package/templates/fe/skeleton-lite/apps/__app__/src/modules/auth/token-store.ts +0 -31
- package/templates/fe/skeleton-lite/apps/web/src/components/frames/SiteShell/classNames.ts +0 -4
|
@@ -42,78 +42,84 @@ components:
|
|
|
42
42
|
environments:
|
|
43
43
|
dev:
|
|
44
44
|
status: supported
|
|
45
|
-
runtime: docker-
|
|
46
|
-
composeFiles: [infra/
|
|
45
|
+
runtime: docker-compose
|
|
46
|
+
composeFiles: [infra/compose/compose.yaml]
|
|
47
47
|
components:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
ingress: {replicas: 1, port: 80}
|
|
48
|
+
db: {port: 54322}
|
|
49
|
+
api: {port: 3001}
|
|
50
|
+
web: {port: 3000}
|
|
52
51
|
runbook: README.md
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
52
|
+
# Dev custody is generated once, dev-only, by the owner-armed `starci app secret init --env dev --execute`, which also declares each key here.
|
|
53
|
+
secrets: []
|
|
54
|
+
# `starci app stack up --env dev --execute` reads this block (PROJECT-STACKS-6): host prerequisites, dev custody, setup, the compose services,
|
|
55
|
+
# the environment's own database role, migrations, native api and web processes, readiness, origins.
|
|
56
|
+
local:
|
|
57
|
+
ports:
|
|
58
|
+
db: 54322
|
|
59
|
+
api: 3001
|
|
60
|
+
web: 3000
|
|
61
|
+
services:
|
|
62
|
+
- {name: db, wait: healthy}
|
|
63
|
+
database:
|
|
64
|
+
service: db
|
|
65
|
+
port: db
|
|
66
|
+
urlEnv: PRIMARY_DB_URL
|
|
67
|
+
appRole: app_be
|
|
68
|
+
password: {member: db, key: DEV_DB_OWNER_PASSWORD}
|
|
69
|
+
adminPassword: {member: db, key: POSTGRES_PASSWORD}
|
|
70
|
+
appPassword: {member: db, key: DEV_DB_APP_PASSWORD}
|
|
71
|
+
grants:
|
|
72
|
+
- {name: db, keys: [POSTGRES_PASSWORD]}
|
|
73
|
+
custody:
|
|
74
|
+
- {member: db, key: POSTGRES_PASSWORD, kind: password}
|
|
75
|
+
- {member: db, key: DEV_DB_OWNER_PASSWORD, kind: password}
|
|
76
|
+
- {member: db, key: DEV_DB_APP_PASSWORD, kind: password}
|
|
77
|
+
- {member: auth, key: AUTH_JWT_PRIVATE_KEY, kind: ed25519-pem}
|
|
78
|
+
- {member: google, key: GOOGLE_CLIENT_SECRET, kind: hex}
|
|
79
|
+
- {member: storage, key: STORAGE_ACCESS_KEY_ID, kind: hex, bytes: 12}
|
|
80
|
+
- {member: storage, key: STORAGE_SECRET_ACCESS_KEY, kind: hex}
|
|
81
|
+
setup:
|
|
82
|
+
- {name: install, argv: [npm, ci], heavy: install, skipIfExists: node_modules}
|
|
83
|
+
- {name: codegen, argv: [npm, run, codegen, --silent], heavy: build}
|
|
84
|
+
processes:
|
|
85
|
+
- name: api
|
|
86
|
+
argv: [npx, ts-node-dev, --respawn, -r, tsconfig-paths/register, apps/api/src/main.ts]
|
|
87
|
+
cwd: be
|
|
88
|
+
port: api
|
|
89
|
+
files: [GOOGLE_CLIENT_SECRET, AUTH_JWT_PRIVATE_KEY, STORAGE_ACCESS_KEY_ID, STORAGE_SECRET_ACCESS_KEY]
|
|
90
|
+
env:
|
|
91
|
+
PORT: "${port.api}"
|
|
92
|
+
HTTP_SECURITY_ALLOWED_ORIGINS: "http://localhost:${port.web}"
|
|
93
|
+
PRIMARY_DB_SCHEMA: public
|
|
94
|
+
GOOGLE_CLIENT_ID: dev-local-client-id
|
|
95
|
+
GOOGLE_CALLBACK_URL: "http://localhost:${port.api}/auth/google/callback"
|
|
96
|
+
AUTH_JWT_ISSUER: "http://localhost:${port.api}"
|
|
97
|
+
AUTH_WEB_ORIGIN: "http://localhost:${port.web}"
|
|
98
|
+
AUTH_JWT_AUDIENCE: {{project}}
|
|
99
|
+
AUTH_JWT_KEY_ID: dev-1
|
|
100
|
+
STORAGE_ENDPOINT: "http://127.0.0.1:9000"
|
|
101
|
+
STORAGE_REGION: us-east-1
|
|
102
|
+
STORAGE_BUCKET: {{project}}-dev
|
|
103
|
+
health: {url: "http://localhost:${port.api}/health/live"}
|
|
104
|
+
- name: web
|
|
105
|
+
argv: [npm, run, dev:fe]
|
|
106
|
+
port: web
|
|
107
|
+
env:
|
|
108
|
+
NEXT_PUBLIC_SITE_URL: "http://localhost:${port.web}"
|
|
109
|
+
NEXT_PUBLIC_API_URL: "http://localhost:${port.api}"
|
|
110
|
+
NEXT_PUBLIC_GRAPHQL_URL: "http://localhost:${port.api}/graphql"
|
|
111
|
+
health: {url: "http://localhost:${port.web}/health/live"}
|
|
112
|
+
ready:
|
|
113
|
+
- {name: api-live, url: "http://localhost:${port.api}/health/live"}
|
|
114
|
+
- {name: api-ready, url: "http://localhost:${port.api}/health/ready"}
|
|
115
|
+
- {name: web-live, url: "http://localhost:${port.web}/health/live"}
|
|
116
|
+
verify:
|
|
117
|
+
- {name: api-live, url: "http://localhost:${port.api}/health/live"}
|
|
118
|
+
- {name: api-ready, url: "http://localhost:${port.api}/health/ready"}
|
|
119
|
+
- {name: web-live, url: "http://localhost:${port.web}/health/live"}
|
|
120
|
+
origins:
|
|
121
|
+
- {name: web, url: "http://localhost:${port.web}"}
|
|
122
|
+
- {name: api, url: "http://localhost:${port.api}"}
|
|
117
123
|
production:
|
|
118
124
|
status: supported
|
|
119
125
|
runtime: docker-swarm
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
# Development stack
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
The dev environment is one command: `starci app stack up --env dev --execute`. It checks the machine, opens the dev custody, runs the setup
|
|
4
|
+
commands, starts the dependencies in Docker Linux containers (the `db` service: the official postgres image plus pgvector, built from
|
|
5
|
+
`.starcistacks/images/db/Dockerfile`), gives the environment its own database role, migrates, runs the seed, starts the api and web
|
|
6
|
+
processes natively and waits for readiness. What it runs is the `local` block of `environments.dev` in `.starcistacks/application-stacks.yaml`
|
|
7
|
+
(PROJECT-STACKS-6 in contexts/project/stacks.md); this runbook never carries a docker command, an agent never runs docker by hand.
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
**A new machine.** Install what `starci app stack doctor --env dev` reports missing (it prints the exact winget, brew or apt step per tool; Node
|
|
10
|
+
from `.nvmrc`, npm, git, Docker with Compose v2 running Linux containers, WSL2 on Windows, sops and age), then run `up`. A fresh clone needs
|
|
11
|
+
nothing else: `up` runs `npm ci` and the codegen itself.
|
|
12
|
+
|
|
13
|
+
**Custody.** Dev values are sealed like any secret and generated once, dev-only: the owner arms `starci app secret init --env dev --execute`, which
|
|
14
|
+
creates every value `local.custody` declares, declares its key in the manifest and never replaces a value that is already sealed. A machine that
|
|
15
|
+
lacks the age identity of an existing dev member is refused with the owner step to obtain it. The `db` service takes `POSTGRES_PASSWORD`, the
|
|
16
|
+
migrations run as the environment's own owner role and the api connects as the `app_be` role with its own password, so no role is shared with
|
|
17
|
+
another environment.
|
|
7
18
|
|
|
8
19
|
| Command | Operation |
|
|
9
20
|
| --- | --- |
|
|
10
|
-
| prepare |
|
|
11
|
-
| doctor |
|
|
12
|
-
| up |
|
|
13
|
-
| status |
|
|
14
|
-
| logs |
|
|
15
|
-
| down |
|
|
16
|
-
| verification |
|
|
17
|
-
|
|
18
|
-
Keep real sealed members under `.starcistacks/dev/secrets/*.enc` at the declared paths and inventory their key names in `.starcistacks/dev/runtime/env/KEYS.md`. Rotation creates a new immutable `-v<N>` external secret and updates its version and runtime name together in the manifest and model. Only the declared ingress publishes port 80; the local route uses HTTP with automatic TLS disabled.
|
|
21
|
+
| prepare | `starci app stack prepare --env dev --execute`: checks the machine, opens the custody, runs the setup commands and builds the images. |
|
|
22
|
+
| doctor | `starci app stack doctor --env dev`: read-only table of host prerequisites with the owner-run install step per OS, custody, compose render and ports. |
|
|
23
|
+
| up | `starci app stack up --env dev --execute`: prepare, then the services, the database role, migrations with a receipt, the seed, the processes and readiness; prints the origins. |
|
|
24
|
+
| status | `starci app stack status --env dev`: desired against running, the migration receipt and every readiness probe. |
|
|
25
|
+
| logs | `starci app stack logs --env dev --service api` (a process or a compose service, bounded and redacted). |
|
|
26
|
+
| down | `starci app stack down --env dev --execute`: ends the processes and stops the compose project; volumes and sealed values stay. |
|
|
27
|
+
| verification | `starci app stack verify --env dev`: the declared liveness and readiness probes after a real start, then `npm run lint` from the app root. |
|
|
19
28
|
|
|
20
|
-
The
|
|
29
|
+
The database volume `db-data` is rebuildable development data: `starci app db migrate` recreates its schema from `db/bootstrap.sql` and
|
|
30
|
+
`db/migrations`. Key names of the environment are in `.starcistacks/dev/runtime/env/KEYS.md`.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# The dev environment's dependencies, run by `starci app stack up --env dev --execute` (PROJECT-STACKS-3, PROJECT-STACKS-6).
|
|
2
|
+
# Host ports come from environments.dev.local.ports through STACK_PORT_<NAME>; the superuser password is read from a file through the least
|
|
3
|
+
# grant STACK_GRANT_DB (a directory holding only POSTGRES_PASSWORD), never from the environment. Every port publishes on loopback only. The api and web run natively against these containers.
|
|
4
|
+
name: {{project}}-dev
|
|
5
|
+
services:
|
|
6
|
+
db:
|
|
7
|
+
build:
|
|
8
|
+
context: ../../../images/db
|
|
9
|
+
image: {{project}}-db:local
|
|
10
|
+
environment:
|
|
11
|
+
POSTGRES_PASSWORD_FILE: /run/secrets/POSTGRES_PASSWORD
|
|
12
|
+
ports:
|
|
13
|
+
- "127.0.0.1:${STACK_PORT_DB}:5432"
|
|
14
|
+
volumes:
|
|
15
|
+
- db-data:/var/lib/postgresql/data
|
|
16
|
+
- ${STACK_GRANT_DB}:/run/secrets:ro
|
|
17
|
+
healthcheck:
|
|
18
|
+
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
|
|
19
|
+
interval: 5s
|
|
20
|
+
timeout: 5s
|
|
21
|
+
retries: 30
|
|
22
|
+
start_period: 10s
|
|
23
|
+
restart: unless-stopped
|
|
24
|
+
volumes:
|
|
25
|
+
db-data: {}
|
|
@@ -1,30 +1,22 @@
|
|
|
1
|
-
# Environment key roster
|
|
1
|
+
# Environment key roster (dev)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Names only. Dev values are generated once by the owner-armed `starci app secret init --env dev --execute`, sealed in
|
|
4
|
+
`.starcistacks/dev/secrets/<member>.enc.yaml` and opened by `starci app stack up --env dev --execute` into private files outside the repository
|
|
5
|
+
(`<KEY>_FILE`, which the back end reads first). The public front-end configuration is supplied by the manifest's `local.processes` environment.
|
|
4
6
|
|
|
5
7
|
| Key | Consumer |
|
|
6
8
|
| --- | --- |
|
|
7
|
-
| `PORT` | API listener |
|
|
8
|
-
| `
|
|
9
|
-
| `
|
|
10
|
-
| `
|
|
11
|
-
| `
|
|
12
|
-
| `GOOGLE_CLIENT_ID` | API Google OAuth client |
|
|
13
|
-
| `GOOGLE_CLIENT_SECRET` | API Google OAuth client
|
|
14
|
-
| `
|
|
15
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
21
|
-
| `STORAGE_REGION` | API storage signing region |
|
|
22
|
-
| `STORAGE_BUCKET` | API storage bucket |
|
|
23
|
-
| `STORAGE_ACCESS_KEY_ID` | API storage credential; `.starcistacks/dev/secrets/storage-access-key-id.enc` maps to external `{{project}}-dev-storage-access-key-id-v1` and mounted `/run/secrets/storage-access-key-id` |
|
|
24
|
-
| `STORAGE_SECRET_ACCESS_KEY` | API storage credential; `.starcistacks/dev/secrets/storage-secret-access-key.enc` maps to external `{{project}}-dev-storage-secret-access-key-v1` and mounted `/run/secrets/storage-secret-access-key` |
|
|
25
|
-
| `DATABASE_URL` | `starci app db` verbs (migrate, dump) and `contract:emit`, from the operator's environment |
|
|
26
|
-
| `NEXT_PUBLIC_SITE_URL` | Front-end site URL |
|
|
27
|
-
| `NEXT_PUBLIC_API_URL` | Front-end auth doors of the API |
|
|
28
|
-
| `NEXT_PUBLIC_GRAPHQL_URL` | Front-end GraphQL transport |
|
|
29
|
-
|
|
30
|
-
Public front-end configuration is supplied at build time and stays outside sealed custody. The database verbs read `DATABASE_URL` from the operator's environment; the GitHub secret store carries only the age identity.
|
|
9
|
+
| `PORT`, `HTTP_SECURITY_ALLOWED_ORIGINS`, `PRIMARY_DB_SCHEMA` | API listener, origin allowlist, primary schema (manifest `local.processes.api.env`) |
|
|
10
|
+
| `PRIMARY_DB_URL` | API least-privilege connection as `app_be` with this environment's own password; composed by the stack verb, read through `PRIMARY_DB_URL_FILE` |
|
|
11
|
+
| `POSTGRES_PASSWORD` | The db service's superuser password (member `db`) |
|
|
12
|
+
| `DEV_DB_OWNER_PASSWORD` | The environment's own owner role, which runs the migrations (member `db`) |
|
|
13
|
+
| `DEV_DB_APP_PASSWORD` | The password of the `app_be` role in this environment's database (member `db`) |
|
|
14
|
+
| `GOOGLE_CLIENT_ID`, `GOOGLE_CALLBACK_URL` | API Google OAuth client and callback (local placeholders in the manifest) |
|
|
15
|
+
| `GOOGLE_CLIENT_SECRET` | API Google OAuth client secret (member `google`) |
|
|
16
|
+
| `AUTH_JWT_ISSUER`, `AUTH_JWT_AUDIENCE`, `AUTH_JWT_KEY_ID` | API access-token claims and key id (the key id is published in the JWKS) |
|
|
17
|
+
| `AUTH_WEB_ORIGIN` | API origin of the web app: where the Google callback lands and the only origin a return address may name |
|
|
18
|
+
| `AUTH_JWT_PRIVATE_KEY` | API Ed25519 (EdDSA) signing key (member `auth`) |
|
|
19
|
+
| `STORAGE_ENDPOINT`, `STORAGE_REGION`, `STORAGE_BUCKET` | API storage address |
|
|
20
|
+
| `STORAGE_ACCESS_KEY_ID`, `STORAGE_SECRET_ACCESS_KEY` | API storage credentials (member `storage`) |
|
|
21
|
+
| `NEXT_PUBLIC_SITE_URL`, `NEXT_PUBLIC_API_URL`, `NEXT_PUBLIC_GRAPHQL_URL` | Front-end site, auth doors and GraphQL transport |
|
|
22
|
+
| `DATABASE_URL` | `starci app db` verbs; the stack verb composes it in memory for the migration |
|
|
@@ -12,6 +12,7 @@ services:
|
|
|
12
12
|
GOOGLE_CLIENT_SECRET_FILE: /run/secrets/google-client-secret
|
|
13
13
|
GOOGLE_CALLBACK_URL: https://api.{{project}}.example.invalid/auth/google/callback
|
|
14
14
|
AUTH_JWT_ISSUER: https://api.{{project}}.example.invalid
|
|
15
|
+
AUTH_WEB_ORIGIN: https://{{project}}.example.invalid
|
|
15
16
|
AUTH_JWT_AUDIENCE: {{project}}
|
|
16
17
|
AUTH_JWT_KEY_ID: production-1
|
|
17
18
|
AUTH_COOKIE_DOMAIN: {{project}}.example.invalid
|
|
@@ -13,10 +13,11 @@ This inventory declares names, consumers and mounted file paths. Scaffolding gen
|
|
|
13
13
|
| `GOOGLE_CLIENT_SECRET` | API Google OAuth client; reads `GOOGLE_CLIENT_SECRET_FILE` at `/run/secrets/google-client-secret` |
|
|
14
14
|
| `GOOGLE_CALLBACK_URL` | API Google OAuth callback door |
|
|
15
15
|
| `AUTH_JWT_ISSUER` | API access-token issuer |
|
|
16
|
+
| `AUTH_WEB_ORIGIN` | API origin of the web app: where the Google callback lands and the only origin a return address may name |
|
|
16
17
|
| `AUTH_JWT_AUDIENCE` | API access-token audience |
|
|
17
18
|
| `AUTH_JWT_KEY_ID` | API signing key id, published in the JWKS |
|
|
18
19
|
| `AUTH_COOKIE_DOMAIN` | API cookie `Domain` (a bare domain such as `example.com`, no scheme or port); optional while the web and the API share one host, required when they are served on different hosts, because a host-only refresh cookie never reaches the web server's forwarded `Cookie` header |
|
|
19
|
-
| `AUTH_JWT_PRIVATE_KEY` | API
|
|
20
|
+
| `AUTH_JWT_PRIVATE_KEY` | API Ed25519 (EdDSA) signing key; reads `AUTH_JWT_PRIVATE_KEY_FILE` at `/run/secrets/auth-jwt-private-key` |
|
|
20
21
|
| `STORAGE_ENDPOINT` | API S3-compatible storage endpoint |
|
|
21
22
|
| `STORAGE_REGION` | API storage signing region |
|
|
22
23
|
| `STORAGE_BUCKET` | API storage bucket |
|
|
@@ -24,25 +24,68 @@ begin
|
|
|
24
24
|
end;
|
|
25
25
|
$$;
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
grant usage on schema auth to app_be;
|
|
28
|
+
grant select, insert, update on table auth.users to app_be;
|
|
29
|
+
grant select, insert on table auth.identities to app_be;
|
|
30
|
+
|
|
31
|
+
-- The device sessions and rotating refresh tokens of @starci/auth. A token is stored by its sha256 only; a rotated token stays,
|
|
32
|
+
-- marked used, so a replay is detected (a replay inside the grace window is a racing tab, an older one ends the session).
|
|
33
|
+
-- identity_attempts counts the sign-in attempts of one address in a window every replica shares (the budget of failures).
|
|
34
|
+
-- The app owns auth.users (db/bootstrap.sql) and the role app_be.
|
|
35
|
+
|
|
36
|
+
create table public.identity_sessions (
|
|
37
|
+
id uuid primary key,
|
|
33
38
|
user_id uuid not null references auth.users (id) on delete cascade,
|
|
34
|
-
|
|
39
|
+
created_at timestamptz not null default now(),
|
|
40
|
+
refreshed_at timestamptz not null default now(),
|
|
41
|
+
user_agent text,
|
|
42
|
+
ip text
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
create index identity_sessions_user_idx on public.identity_sessions (user_id);
|
|
46
|
+
|
|
47
|
+
create table public.identity_refresh_tokens (
|
|
48
|
+
id uuid primary key default gen_random_uuid(),
|
|
49
|
+
session_id uuid not null references public.identity_sessions (id) on delete cascade,
|
|
50
|
+
user_id uuid not null,
|
|
51
|
+
token_hash text not null,
|
|
52
|
+
created_at timestamptz not null default now(),
|
|
35
53
|
expires_at timestamptz not null,
|
|
36
|
-
|
|
37
|
-
|
|
54
|
+
used_at timestamptz,
|
|
55
|
+
constraint identity_refresh_tokens_hash_key unique (token_hash)
|
|
38
56
|
);
|
|
39
57
|
|
|
40
|
-
create index
|
|
58
|
+
create index identity_refresh_tokens_session_idx on public.identity_refresh_tokens (session_id);
|
|
59
|
+
create index identity_refresh_tokens_expiry_idx on public.identity_refresh_tokens (user_id, expires_at);
|
|
41
60
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
61
|
+
create table public.identity_attempts (
|
|
62
|
+
key varchar(128) primary key,
|
|
63
|
+
hits integer not null,
|
|
64
|
+
reset_at timestamptz not null
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
create index identity_attempts_reset_idx on public.identity_attempts (reset_at);
|
|
68
|
+
|
|
69
|
+
alter table public.identity_sessions enable row level security;
|
|
70
|
+
alter table public.identity_sessions force row level security;
|
|
71
|
+
alter table public.identity_refresh_tokens enable row level security;
|
|
72
|
+
alter table public.identity_refresh_tokens force row level security;
|
|
73
|
+
alter table public.identity_attempts enable row level security;
|
|
74
|
+
alter table public.identity_attempts force row level security;
|
|
75
|
+
|
|
76
|
+
revoke all on table public.identity_sessions from public;
|
|
77
|
+
revoke all on table public.identity_refresh_tokens from public;
|
|
78
|
+
revoke all on table public.identity_attempts from public;
|
|
79
|
+
grant select, insert, update, delete on table public.identity_sessions to app_be;
|
|
80
|
+
grant select, insert, update, delete on table public.identity_refresh_tokens to app_be;
|
|
81
|
+
grant select, insert, update, delete on table public.identity_attempts to app_be;
|
|
82
|
+
|
|
83
|
+
create policy identity_sessions_app_be_all on public.identity_sessions
|
|
84
|
+
for all to app_be using (current_user = 'app_be') with check (current_user = 'app_be');
|
|
85
|
+
create policy identity_refresh_tokens_app_be_all on public.identity_refresh_tokens
|
|
86
|
+
for all to app_be using (current_user = 'app_be') with check (current_user = 'app_be');
|
|
87
|
+
create policy identity_attempts_app_be_all on public.identity_attempts
|
|
88
|
+
for all to app_be using (current_user = 'app_be') with check (current_user = 'app_be');
|
|
46
89
|
|
|
47
90
|
create table public.profiles (
|
|
48
91
|
id uuid primary key references auth.users (id) on delete cascade,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import type { HttpExchange } from "@modules/integrations/passport"
|
|
3
|
+
|
|
4
|
+
/** One cookie door of sign-in: the request and response the strategy or the refresh cookie work on. */
|
|
5
|
+
export interface ExchangeRequest {
|
|
6
|
+
/** The request and response. */
|
|
7
|
+
readonly exchange: HttpExchange
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** A request with nothing in it. */
|
|
11
|
+
export type EmptyRequest = Record<string, never>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { QueryHandler } from "@nestjs/cqrs"
|
|
3
|
+
import { IdentitySignInService } from "@modules/domain/identity"
|
|
4
|
+
import type { JwksDocument } from "@modules/integrations/passport"
|
|
5
|
+
import { ICQRSHandler } from "@modules/platform/cqrs"
|
|
6
|
+
import { InjectLogger } from "@modules/platform/logging"
|
|
7
|
+
import type { Logger } from "@modules/platform/logging"
|
|
8
|
+
import { GetJwksQuery } from "./get-jwks.query"
|
|
9
|
+
|
|
10
|
+
@QueryHandler(GetJwksQuery)
|
|
11
|
+
/** Answers the JWKS. */
|
|
12
|
+
export class GetJwksHandler extends ICQRSHandler<GetJwksQuery, JwksDocument> {
|
|
13
|
+
constructor(
|
|
14
|
+
@InjectLogger() logger: Logger,
|
|
15
|
+
private readonly signIn: IdentitySignInService,
|
|
16
|
+
) {
|
|
17
|
+
super(logger)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
protected override process(): Promise<JwksDocument> {
|
|
21
|
+
return this.signIn.jwks()
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { Query } from "@nestjs/cqrs"
|
|
3
|
+
import type { JwksDocument } from "@modules/integrations/passport"
|
|
4
|
+
import type { PublicExecuteParams } from "@modules/platform/cqrs"
|
|
5
|
+
import type { EmptyRequest } from "./auth.contracts"
|
|
6
|
+
|
|
7
|
+
/** Reads the public key document access tokens verify against. */
|
|
8
|
+
export class GetJwksQuery extends Query<JwksDocument> {
|
|
9
|
+
constructor(readonly params: PublicExecuteParams<EmptyRequest>) {
|
|
10
|
+
super()
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { Command } from "@nestjs/cqrs"
|
|
3
|
+
import type { PublicExecuteParams } from "@modules/platform/cqrs"
|
|
4
|
+
import type { ExchangeRequest } from "./auth.contracts"
|
|
5
|
+
|
|
6
|
+
/** Starts the Google round trip: the strategy writes the redirect and the signed state cookie. */
|
|
7
|
+
export class GoogleBeginCommand extends Command<void> {
|
|
8
|
+
constructor(readonly params: PublicExecuteParams<ExchangeRequest>) {
|
|
9
|
+
super()
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { CommandHandler } from "@nestjs/cqrs"
|
|
3
|
+
import { IdentitySignInService } from "@modules/domain/identity"
|
|
4
|
+
import { ICQRSHandler } from "@modules/platform/cqrs"
|
|
5
|
+
import { InjectLogger } from "@modules/platform/logging"
|
|
6
|
+
import type { Logger } from "@modules/platform/logging"
|
|
7
|
+
import { GoogleBeginCommand } from "./google-begin.command"
|
|
8
|
+
|
|
9
|
+
@CommandHandler(GoogleBeginCommand)
|
|
10
|
+
/** Starts the Google round trip: the strategy writes the redirect and the signed state cookie. */
|
|
11
|
+
export class GoogleBeginHandler extends ICQRSHandler<GoogleBeginCommand, void> {
|
|
12
|
+
constructor(
|
|
13
|
+
@InjectLogger() logger: Logger,
|
|
14
|
+
private readonly signIn: IdentitySignInService,
|
|
15
|
+
) {
|
|
16
|
+
super(logger)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
protected override process(command: GoogleBeginCommand): Promise<void> {
|
|
20
|
+
return this.signIn.beginGoogle(command.params.request.exchange)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { Command } from "@nestjs/cqrs"
|
|
3
|
+
import type { GoogleRedirect } from "@modules/integrations/passport"
|
|
4
|
+
import type { PublicExecuteParams } from "@modules/platform/cqrs"
|
|
5
|
+
import type { ExchangeRequest } from "./auth.contracts"
|
|
6
|
+
|
|
7
|
+
/** Finishes the Google round trip. */
|
|
8
|
+
export class GoogleCompleteCommand extends Command<GoogleRedirect> {
|
|
9
|
+
constructor(readonly params: PublicExecuteParams<ExchangeRequest>) {
|
|
10
|
+
super()
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { CommandHandler } from "@nestjs/cqrs"
|
|
3
|
+
import { IdentitySignInService } from "@modules/domain/identity"
|
|
4
|
+
import type { GoogleRedirect } from "@modules/integrations/passport"
|
|
5
|
+
import { ICQRSHandler } from "@modules/platform/cqrs"
|
|
6
|
+
import { InjectLogger } from "@modules/platform/logging"
|
|
7
|
+
import type { Logger } from "@modules/platform/logging"
|
|
8
|
+
import { GoogleCompleteCommand } from "./google-complete.command"
|
|
9
|
+
|
|
10
|
+
@CommandHandler(GoogleCompleteCommand)
|
|
11
|
+
/** Finishes the Google round trip. */
|
|
12
|
+
export class GoogleCompleteHandler extends ICQRSHandler<GoogleCompleteCommand, GoogleRedirect> {
|
|
13
|
+
constructor(
|
|
14
|
+
@InjectLogger() logger: Logger,
|
|
15
|
+
private readonly signIn: IdentitySignInService,
|
|
16
|
+
) {
|
|
17
|
+
super(logger)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
protected override process(command: GoogleCompleteCommand): Promise<GoogleRedirect> {
|
|
21
|
+
return this.signIn.completeGoogle(command.params.request.exchange)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { Command } from "@nestjs/cqrs"
|
|
3
|
+
import type { AccessGrant } from "@modules/integrations/passport"
|
|
4
|
+
import type { PublicExecuteParams } from "@modules/platform/cqrs"
|
|
5
|
+
import type { ExchangeRequest } from "./auth.contracts"
|
|
6
|
+
|
|
7
|
+
/** Signs in with email and password through the local strategy and opens a session. */
|
|
8
|
+
export class LoginCommand extends Command<AccessGrant> {
|
|
9
|
+
constructor(readonly params: PublicExecuteParams<ExchangeRequest>) {
|
|
10
|
+
super()
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { CommandHandler } from "@nestjs/cqrs"
|
|
3
|
+
import { IdentitySignInService } from "@modules/domain/identity"
|
|
4
|
+
import type { AccessGrant } from "@modules/integrations/passport"
|
|
5
|
+
import { ICQRSHandler } from "@modules/platform/cqrs"
|
|
6
|
+
import { InjectLogger } from "@modules/platform/logging"
|
|
7
|
+
import type { Logger } from "@modules/platform/logging"
|
|
8
|
+
import { LoginCommand } from "./login.command"
|
|
9
|
+
|
|
10
|
+
@CommandHandler(LoginCommand)
|
|
11
|
+
/** Signs in with email and password through the local strategy and opens a session. */
|
|
12
|
+
export class LoginHandler extends ICQRSHandler<LoginCommand, AccessGrant> {
|
|
13
|
+
constructor(
|
|
14
|
+
@InjectLogger() logger: Logger,
|
|
15
|
+
private readonly signIn: IdentitySignInService,
|
|
16
|
+
) {
|
|
17
|
+
super(logger)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
protected override process(command: LoginCommand): Promise<AccessGrant> {
|
|
21
|
+
return this.signIn.login(command.params.request.exchange)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { Command } from "@nestjs/cqrs"
|
|
3
|
+
import type { PublicExecuteParams } from "@modules/platform/cqrs"
|
|
4
|
+
import type { ExchangeRequest } from "./auth.contracts"
|
|
5
|
+
|
|
6
|
+
/** Ends the session of the refresh cookie and clears it. */
|
|
7
|
+
export class LogoutCommand extends Command<void> {
|
|
8
|
+
constructor(readonly params: PublicExecuteParams<ExchangeRequest>) {
|
|
9
|
+
super()
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { CommandHandler } from "@nestjs/cqrs"
|
|
3
|
+
import { IdentitySignInService } from "@modules/domain/identity"
|
|
4
|
+
import { ICQRSHandler } from "@modules/platform/cqrs"
|
|
5
|
+
import { InjectLogger } from "@modules/platform/logging"
|
|
6
|
+
import type { Logger } from "@modules/platform/logging"
|
|
7
|
+
import { LogoutCommand } from "./logout.command"
|
|
8
|
+
|
|
9
|
+
@CommandHandler(LogoutCommand)
|
|
10
|
+
/** Ends the session of the refresh cookie and clears it. */
|
|
11
|
+
export class LogoutHandler extends ICQRSHandler<LogoutCommand, void> {
|
|
12
|
+
constructor(
|
|
13
|
+
@InjectLogger() logger: Logger,
|
|
14
|
+
private readonly signIn: IdentitySignInService,
|
|
15
|
+
) {
|
|
16
|
+
super(logger)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
protected override process(command: LogoutCommand): Promise<void> {
|
|
20
|
+
return this.signIn.logout(command.params.request.exchange)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Managed by starci app sync (slot be.feature.auth); do not edit: run "npx starci app sync --execute".
|
|
2
|
+
import { Command } from "@nestjs/cqrs"
|
|
3
|
+
import type { AccessGrant } from "@modules/integrations/passport"
|
|
4
|
+
import type { PublicExecuteParams } from "@modules/platform/cqrs"
|
|
5
|
+
import type { ExchangeRequest } from "./auth.contracts"
|
|
6
|
+
|
|
7
|
+
/** Rotates the refresh cookie and answers a new access token; a bad cookie is cleared. */
|
|
8
|
+
export class RefreshCommand extends Command<AccessGrant> {
|
|
9
|
+
constructor(readonly params: PublicExecuteParams<ExchangeRequest>) {
|
|
10
|
+
super()
|
|
11
|
+
}
|
|
12
|
+
}
|