@c9up/station 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/StationProvider.d.ts +51 -11
- package/dist/StationProvider.d.ts.map +1 -1
- package/dist/StationProvider.js +484 -163
- package/dist/StationProvider.js.map +1 -1
- package/dist/columns.d.ts +38 -0
- package/dist/columns.d.ts.map +1 -0
- package/dist/columns.js +93 -0
- package/dist/columns.js.map +1 -0
- package/dist/defineResource.d.ts.map +1 -1
- package/dist/defineResource.js +24 -0
- package/dist/defineResource.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loginLimiter.d.ts +41 -0
- package/dist/loginLimiter.d.ts.map +1 -0
- package/dist/loginLimiter.js +80 -0
- package/dist/loginLimiter.js.map +1 -0
- package/dist/types.d.ts +74 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/views/form.d.ts +6 -0
- package/dist/views/form.d.ts.map +1 -1
- package/dist/views/form.js +4 -4
- package/dist/views/form.js.map +1 -1
- package/dist/views/login.d.ts +2 -2
- package/dist/views/login.js +2 -2
- package/package.json +1 -1
- package/src/StationProvider.ts +675 -184
- package/src/columns.ts +136 -0
- package/src/defineResource.ts +32 -0
- package/src/index.ts +7 -0
- package/src/loginLimiter.ts +110 -0
- package/src/types.ts +86 -1
- package/src/views/form.ts +26 -4
- package/src/views/login.ts +2 -2
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import "./augmentations.js";
|
|
21
21
|
import type { ColumnMetadata } from "@c9up/atlas";
|
|
22
|
-
import type
|
|
22
|
+
import { type StationLoginRateLimitConfig } from "./loginLimiter.js";
|
|
23
|
+
import type { Resource, SecurityAuditSink } from "./types.js";
|
|
23
24
|
/**
|
|
24
25
|
* Duck-typed slice of the host's IoC container — Station MUST stay
|
|
25
26
|
* publishable without importing `@c9up/ream` directly (memory
|
|
@@ -99,11 +100,23 @@ export interface StationConfig {
|
|
|
99
100
|
*/
|
|
100
101
|
requireAuth?: boolean;
|
|
101
102
|
/**
|
|
102
|
-
* Role required to pass the auth gate
|
|
103
|
-
* authenticated user can access `/admin/*` (the per-action
|
|
104
|
-
* `<resource>.<action>` permission gate still applies).
|
|
103
|
+
* Role required to pass the auth gate, on top of {@link accessPermission}.
|
|
105
104
|
*/
|
|
106
105
|
requireRole?: string;
|
|
106
|
+
/**
|
|
107
|
+
* Namespace of every admin permission: actions are gated behind
|
|
108
|
+
* `<prefix>.<resource>.<action>` (e.g. `station.users.edit`) and entry
|
|
109
|
+
* behind `<prefix>.access`. Defaults to `"station"`, so a grant the
|
|
110
|
+
* application made for its own features (`users.edit`) never opens the
|
|
111
|
+
* admin.
|
|
112
|
+
*/
|
|
113
|
+
permissionPrefix?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Permission every request must hold to enter `/admin/*`, checked before
|
|
116
|
+
* the per-action one. Defaults to `<permissionPrefix>.access`. `false`
|
|
117
|
+
* removes this gate (the per-action permissions still apply).
|
|
118
|
+
*/
|
|
119
|
+
accessPermission?: string | false;
|
|
107
120
|
/**
|
|
108
121
|
* Where to redirect on a failed auth check. Defaults to
|
|
109
122
|
* `/admin/login`.
|
|
@@ -114,6 +127,29 @@ export interface StationConfig {
|
|
|
114
127
|
* to avoid colliding with app-level session cookies.
|
|
115
128
|
*/
|
|
116
129
|
cookieName?: string;
|
|
130
|
+
/**
|
|
131
|
+
* `Secure` flag of the auth cookie. Defaults to on everywhere except a
|
|
132
|
+
* development/test process served over plain HTTP, so an unknown
|
|
133
|
+
* environment behaves like production.
|
|
134
|
+
*/
|
|
135
|
+
cookieSecure?: boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Brute-force throttle on `POST /admin/login`: 5 attempts per IP and per
|
|
138
|
+
* identifier every 15 minutes by default, in this process's memory. Pass
|
|
139
|
+
* `limiter` (warden's `AuthRateLimiter` fits) to share counts across
|
|
140
|
+
* instances. `false` turns it off — only for an app that throttles the
|
|
141
|
+
* route itself (see {@link middleware}).
|
|
142
|
+
*/
|
|
143
|
+
loginRateLimit?: StationLoginRateLimitConfig | false;
|
|
144
|
+
/** Named router middleware attached to every route Station mounts. */
|
|
145
|
+
middleware?: ReadonlyArray<string>;
|
|
146
|
+
/**
|
|
147
|
+
* Sink for the admin's security events: sign-in success, failure and
|
|
148
|
+
* throttling, logout, authorization denials and CSRF blocks, each with the
|
|
149
|
+
* client IP and request id. Write events keep going to each resource's
|
|
150
|
+
* own `audit`.
|
|
151
|
+
*/
|
|
152
|
+
audit?: SecurityAuditSink;
|
|
117
153
|
}
|
|
118
154
|
/** @internal Reset module-level flags between tests. */
|
|
119
155
|
export declare function resetStationProviderFlags(): void;
|
|
@@ -130,9 +166,9 @@ export declare function resourcesNeedValidation(resources: ReadonlyArray<Resourc
|
|
|
130
166
|
* Derive a `@c9up/rune` validation schema (57.7) from an entity's writable
|
|
131
167
|
* column metadata — the structural replacement for the hand-rolled
|
|
132
168
|
* `filterWritableBody`. The mass-assignment guarantee is now INHERENT:
|
|
133
|
-
* `schema.validateResult()` returns only
|
|
134
|
-
*
|
|
135
|
-
*
|
|
169
|
+
* `schema.validateResult()` returns only the keys of the editable columns it
|
|
170
|
+
* was given, so any other body key — an unknown one, a column outside the
|
|
171
|
+
* allow-list, the PK, a timestamp — is dropped automatically.
|
|
136
172
|
*
|
|
137
173
|
* Excluded, exactly as the old guard did: the primary key, framework-managed
|
|
138
174
|
* timestamps (both the Lucid-style `autoManaged` flag AND the `created_at /
|
|
@@ -153,10 +189,13 @@ export declare function resourcesNeedValidation(resources: ReadonlyArray<Resourc
|
|
|
153
189
|
* Returns the built schema plus the set of boolean columns — the handler
|
|
154
190
|
* default-fills an ABSENT boolean key to `false` before validating (an
|
|
155
191
|
* unchecked checkbox submits nothing; this preserves the old edit-clears-box
|
|
156
|
-
* behaviour).
|
|
192
|
+
* behaviour). `columns` is the editable allow-list; framework-owned columns
|
|
193
|
+
* are dropped here too, so no caller can make them writable. `updateSchema`
|
|
194
|
+
* differs only for `writeOnly` columns, which an edit may leave out.
|
|
157
195
|
*/
|
|
158
|
-
export declare function deriveWritableSchema(columns: ReadonlyArray<ColumnMetadata>, pkColumn: string, autoManaged: ReadonlySet<string>, excludedProps: ReadonlySet<string>, rune: RuneModule): {
|
|
196
|
+
export declare function deriveWritableSchema(columns: ReadonlyArray<ColumnMetadata>, pkColumn: string, autoManaged: ReadonlySet<string>, excludedProps: ReadonlySet<string>, rune: RuneModule, writeOnly?: ReadonlySet<string>): {
|
|
159
197
|
schema: RuneSchema;
|
|
198
|
+
updateSchema: RuneSchema;
|
|
160
199
|
booleanKeys: ReadonlySet<string>;
|
|
161
200
|
};
|
|
162
201
|
/**
|
|
@@ -165,9 +204,10 @@ export declare function deriveWritableSchema(columns: ReadonlyArray<ColumnMetada
|
|
|
165
204
|
* preserving the old `filterWritableBody` checkbox semantics, then runs rune's
|
|
166
205
|
* synchronous, never-throwing `validateResult()`. On success `result.data` holds only
|
|
167
206
|
* declared-column keys (mass-assignment inherent). Exported for the unit tests
|
|
168
|
-
* that pin the coercion CRUX.
|
|
207
|
+
* that pin the coercion CRUX. A blank `writeOnly` value counts as not
|
|
208
|
+
* submitted: the form never pre-fills those, so blank means "unchanged".
|
|
169
209
|
*/
|
|
170
|
-
export declare function validateWritableBody(schema: RuneSchema, booleanKeys: ReadonlySet<string>, body: Record<string, unknown>): RuneValidationResult;
|
|
210
|
+
export declare function validateWritableBody(schema: RuneSchema, booleanKeys: ReadonlySet<string>, body: Record<string, unknown>, writeOnly?: ReadonlySet<string>): RuneValidationResult;
|
|
171
211
|
export default class StationProvider {
|
|
172
212
|
#private;
|
|
173
213
|
protected app: StationAppContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StationProvider.d.ts","sourceRoot":"","sources":["../src/StationProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAEX,cAAc,EAGd,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"StationProvider.d.ts","sourceRoot":"","sources":["../src/StationProvider.ts"],"names":[],"mappings":"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"}
|