@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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loginLimiter.js","sourceRoot":"","sources":["../src/loginLimiter.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -13,9 +13,44 @@ export interface AuditEvent {
13
13
  readonly userId?: unknown;
14
14
  readonly before?: Readonly<Record<string, unknown>>;
15
15
  readonly after?: Readonly<Record<string, unknown>>;
16
+ /**
17
+ * On an edit, the secret columns whose value changed. Their values are
18
+ * replaced with `"[redacted]"` in `before`/`after` (unless the resource
19
+ * sets `auditSecrets`), so this is how a password change stays visible.
20
+ */
21
+ readonly redactedChanges?: ReadonlyArray<string>;
22
+ /** Client IP of the request that made the change. */
23
+ readonly ip?: string;
24
+ readonly userAgent?: string;
25
+ /** `X-Request-Id` of that request, when the proxy or client set one. */
26
+ readonly requestId?: string;
16
27
  readonly at: Date;
17
28
  }
18
29
  export type AuditSink = (event: AuditEvent) => void | Promise<void>;
30
+ /** What a {@link SecurityAuditEvent} records. */
31
+ export type SecurityAuditAction = "login" | "login_failed" | "login_throttled" | "logout" | "denied" | "csrf_denied";
32
+ /**
33
+ * A sign-in, sign-out or refusal on the admin surface, sent to the
34
+ * `station.audit` sink so brute force and probing show up in the trail.
35
+ */
36
+ export interface SecurityAuditEvent {
37
+ readonly action: SecurityAuditAction;
38
+ /** The authenticated user, when one is known. */
39
+ readonly userId?: unknown;
40
+ /** The email a sign-in attempt submitted. */
41
+ readonly identifier?: string;
42
+ /** For `denied` on a resource action: its slug, action and permission. */
43
+ readonly resource?: string;
44
+ readonly resourceAction?: ResourceAction;
45
+ /** For `denied`: the permission or role that was missing. */
46
+ readonly permission?: string;
47
+ readonly path?: string;
48
+ readonly ip?: string;
49
+ readonly userAgent?: string;
50
+ readonly requestId?: string;
51
+ readonly at: Date;
52
+ }
53
+ export type SecurityAuditSink = (event: SecurityAuditEvent) => void | Promise<void>;
19
54
  /**
20
55
  * Per-field override for the auto-generated form (Story 54.5). Station
21
56
  * infers the form from the entity's `@Column` metadata; consumers can
@@ -23,7 +58,10 @@ export type AuditSink = (event: AuditEvent) => void | Promise<void>;
23
58
  * others.
24
59
  */
25
60
  export interface FormFieldOverride {
26
- /** Hide the field from the form entirely (still rendered on show). */
61
+ /**
62
+ * Hide the field from the form. A hidden field is not writable either: a
63
+ * body carrying it is ignored and a hidden boolean keeps its stored value.
64
+ */
27
65
  hidden?: boolean;
28
66
  /** Override the rendered `<input type>`. */
29
67
  inputType?: "text" | "number" | "email" | "password" | "date" | "datetime-local" | "checkbox" | "textarea";
@@ -34,6 +72,14 @@ export interface FormFieldOverride {
34
72
  /** Mark the field as required at the HTML level. */
35
73
  required?: boolean;
36
74
  }
75
+ /** Per-view options for the list and show pages. */
76
+ export interface ResourceViewOptions {
77
+ /**
78
+ * The columns the view renders, in this order. When omitted, every column
79
+ * except secrets (`serializeAs: null` or a credential-like name) is shown.
80
+ */
81
+ columns?: ReadonlyArray<string>;
82
+ }
37
83
  export interface ResourceOptions<TEntity> {
38
84
  /** Entity class (Atlas `@Entity()`-decorated constructor). */
39
85
  entity: new (...args: never[]) => TEntity;
@@ -49,6 +95,13 @@ export interface ResourceOptions<TEntity> {
49
95
  * so apps don't silently lose audit visibility.
50
96
  */
51
97
  audit?: AuditSink;
98
+ /**
99
+ * Hand secret column values (`serializeAs: null` or a credential-like
100
+ * name) to the audit sink as they are. Off by default: they are replaced
101
+ * with `"[redacted]"`, because audit logs usually land in a less protected
102
+ * store than the table they describe.
103
+ */
104
+ auditSecrets?: boolean;
52
105
  /**
53
106
  * Invoked when the audit sink throws (Story 54.6 hardening, retro
54
107
  * 2026-06-01). The mutation has already committed, so this is a
@@ -65,6 +118,18 @@ export interface ResourceOptions<TEntity> {
65
118
  * the inferred defaults.
66
119
  */
67
120
  formFields?: Readonly<Record<string, FormFieldOverride>>;
121
+ /** Columns of the list page. */
122
+ list?: ResourceViewOptions;
123
+ /** Columns of the show page. */
124
+ show?: ResourceViewOptions;
125
+ /**
126
+ * The columns a create/edit may set, and the fields the form shows. When
127
+ * omitted: every column except the framework-managed ones, secrets
128
+ * (`serializeAs: null` or a credential-like name) and `formFields` marked
129
+ * `hidden`. A secret listed here is write-only: the form renders it empty
130
+ * and an empty submission keeps the stored value.
131
+ */
132
+ editable?: ReadonlyArray<string>;
68
133
  }
69
134
  export interface Resource<TEntity = unknown> {
70
135
  /** The entity class passed in. */
@@ -77,9 +142,17 @@ export interface Resource<TEntity = unknown> {
77
142
  readonly actions: ReadonlyArray<ResourceAction>;
78
143
  /** Optional audit sink (Story 54.6). */
79
144
  readonly audit?: AuditSink;
145
+ /** Whether audit snapshots keep secret column values. */
146
+ readonly auditSecrets: boolean;
80
147
  /** Optional audit-failure observability hook (Story 54.6 hardening). */
81
148
  readonly onAuditError?: (event: AuditEvent, error: unknown) => void;
82
149
  /** Frozen per-field overrides for the inferred form (Story 54.5). */
83
150
  readonly formFields: Readonly<Record<string, FormFieldOverride>>;
151
+ /** Frozen list-page options. */
152
+ readonly list: Readonly<ResourceViewOptions>;
153
+ /** Frozen show-page options. */
154
+ readonly show: Readonly<ResourceViewOptions>;
155
+ /** Frozen editable allow-list; undefined means the default set. */
156
+ readonly editable?: ReadonlyArray<string>;
84
157
  }
85
158
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7E,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,cAAc,CAMzD,CAAC;AAEH;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4CAA4C;IAC5C,SAAS,CAAC,EACP,MAAM,GACN,QAAQ,GACR,OAAO,GACP,UAAU,GACV,MAAM,GACN,gBAAgB,GAChB,UAAU,GACV,UAAU,CAAC;IACd,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe,CAAC,OAAO;IACvC,8DAA8D;IAC9D,MAAM,EAAE,KACP,GAAG,IAAI,EAAE,KAAK,EAAE,KACZ,OAAO,CAAC;IACb,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,OAAO,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IACxC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3D;;;;OAIG;IACH,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,QAAQ,CAAC,OAAO,GAAG,OAAO;IAC1C,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,KAChB,GAAG,IAAI,EAAE,KAAK,EAAE,KACZ,OAAO,CAAC;IACb,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IAChD,wCAAwC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACpE,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;CACjE"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,12 @@ export interface FormPageInput {
39
39
  values?: Readonly<Record<string, unknown>>;
40
40
  /** Validation errors keyed by column propertyKey. */
41
41
  errors?: Readonly<Record<string, string>>;
42
+ /**
43
+ * Fields rendered empty whatever their stored or submitted value (secrets).
44
+ * A `password` input is always treated this way: a credential, even a hash,
45
+ * is never shipped back inside the page.
46
+ */
47
+ writeOnly?: ReadonlySet<string>;
42
48
  /**
43
49
  * Whether the host has a CSRF token in the per-request store. When true the
44
50
  * template emits `{{ csrfField() }}`; the handler derives it from
@@ -1 +1 @@
1
- {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../src/views/form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQ/D,KAAK,SAAS,GAAG,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3C,qDAAqD;IACrD,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1C;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACd;AAKD,MAAM,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,SAAS,EAAE,CAAC;CACpB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CAmCtE"}
1
+ {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../src/views/form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQ/D,KAAK,SAAS,GAAG,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3C,qDAAqD;IACrD,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1C;;;;OAIG;IACH,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACd;AAKD,MAAM,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,SAAS,EAAE,CAAC;CACpB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CAiDtE"}
@@ -25,7 +25,7 @@ const SKIPPED_COLUMN_NAMES = new Set([
25
25
  "deleted_at",
26
26
  ]);
27
27
  export function buildFormViewModel(input) {
28
- const { resource, columns, pkColumn, row, values, errors, csrfEnabled } = input;
28
+ const { resource, columns, pkColumn, row, values, errors, csrfEnabled, writeOnly, } = input;
29
29
  const isEdit = row !== undefined;
30
30
  const slug = encodeURIComponent(resource.name);
31
31
  const id = isEdit ? String(row[pkColumn] ?? "") : "";
@@ -41,7 +41,7 @@ export function buildFormViewModel(input) {
41
41
  : ["New ", resource.label].join("");
42
42
  const fields = columns
43
43
  .filter((c) => !shouldSkipColumn(c, pkColumn, resource.formFields[c.propertyKey]))
44
- .map((c) => buildField(c, values ?? row, errors, resource.formFields[c.propertyKey]));
44
+ .map((c) => buildField(c, values ?? row, errors, resource.formFields[c.propertyKey], writeOnly?.has(c.propertyKey) === true));
45
45
  return {
46
46
  title: heading,
47
47
  heading,
@@ -53,10 +53,10 @@ export function buildFormViewModel(input) {
53
53
  fields,
54
54
  };
55
55
  }
56
- function buildField(c, source, errors, override) {
56
+ function buildField(c, source, errors, override, writeOnly) {
57
57
  const inputType = override?.inputType ?? inferInputType(c);
58
58
  const name = c.propertyKey;
59
- const rawValue = source?.[name];
59
+ const rawValue = writeOnly || inputType === "password" ? undefined : source?.[name];
60
60
  const isCheckbox = inputType === "checkbox";
61
61
  const value = rawValue === undefined || rawValue === null ? "" : String(rawValue);
62
62
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/views/form.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/views/form.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,8 @@
7
7
  *
8
8
  * Pure `(input) => LoginViewModel` builder (Story 57.3): every value reaches
9
9
  * HTML through `templates/login.inker`'s `{{ }}` auto-escape (the retired
10
- * `escape.ts` no longer runs here), so a tampered `?error=…` query parameter
11
- * cannot smuggle markup into the page. The CSRF hidden input is emitted by
10
+ * `escape.ts` no longer runs here). `error` only ever carries a message
11
+ * Station produced; the handler never reads it from the URL. The CSRF hidden input is emitted by
12
12
  * inker's canonical `{{ csrfField() }}` helper, guarded by the precomputed
13
13
  * `csrfEnabled` boolean.
14
14
  */
@@ -7,8 +7,8 @@
7
7
  *
8
8
  * Pure `(input) => LoginViewModel` builder (Story 57.3): every value reaches
9
9
  * HTML through `templates/login.inker`'s `{{ }}` auto-escape (the retired
10
- * `escape.ts` no longer runs here), so a tampered `?error=…` query parameter
11
- * cannot smuggle markup into the page. The CSRF hidden input is emitted by
10
+ * `escape.ts` no longer runs here). `error` only ever carries a message
11
+ * Station produced; the handler never reads it from the URL. The CSRF hidden input is emitted by
12
12
  * inker's canonical `{{ csrfField() }}` helper, guarded by the precomputed
13
13
  * `csrfEnabled` boolean.
14
14
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/station",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Station — admin scaffolding for the Ream framework. Declarative resource catalogue (defineResource) backing list/show/create/edit/destroy routes, audit, policies.",
5
5
  "license": "MIT",
6
6
  "type": "module",