@ontrails/permits 1.0.0-beta.14 → 1.0.0-beta.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.
Files changed (89) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +35 -27
  3. package/package.json +12 -3
  4. package/src/adapters/adapter.ts +41 -0
  5. package/src/{connectors → adapters}/jwt.ts +148 -21
  6. package/src/auth-resource.ts +89 -0
  7. package/src/boundary.ts +200 -0
  8. package/src/errors.ts +1 -18
  9. package/src/extraction.ts +22 -16
  10. package/src/index.ts +22 -10
  11. package/src/permit.ts +2 -2
  12. package/src/rules.ts +2 -2
  13. package/src/testing.ts +5 -5
  14. package/src/trails/auth-verify.ts +13 -15
  15. package/.turbo/turbo-build.log +0 -1
  16. package/.turbo/turbo-lint.log +0 -3
  17. package/.turbo/turbo-typecheck.log +0 -1
  18. package/dist/adapter.d.ts +0 -26
  19. package/dist/adapter.d.ts.map +0 -1
  20. package/dist/adapter.js +0 -2
  21. package/dist/adapter.js.map +0 -1
  22. package/dist/adapters/jwt.d.ts +0 -25
  23. package/dist/adapters/jwt.d.ts.map +0 -1
  24. package/dist/adapters/jwt.js +0 -148
  25. package/dist/adapters/jwt.js.map +0 -1
  26. package/dist/auth-gate.d.ts +0 -18
  27. package/dist/auth-gate.d.ts.map +0 -1
  28. package/dist/auth-gate.js +0 -56
  29. package/dist/auth-gate.js.map +0 -1
  30. package/dist/auth-layer.d.ts +0 -18
  31. package/dist/auth-layer.d.ts.map +0 -1
  32. package/dist/auth-layer.js +0 -56
  33. package/dist/auth-layer.js.map +0 -1
  34. package/dist/auth-provision.d.ts +0 -11
  35. package/dist/auth-provision.d.ts.map +0 -1
  36. package/dist/auth-provision.js +0 -22
  37. package/dist/auth-provision.js.map +0 -1
  38. package/dist/auth-service.d.ts +0 -10
  39. package/dist/auth-service.d.ts.map +0 -1
  40. package/dist/auth-service.js +0 -21
  41. package/dist/auth-service.js.map +0 -1
  42. package/dist/connectors/connector.d.ts +0 -26
  43. package/dist/connectors/connector.d.ts.map +0 -1
  44. package/dist/connectors/connector.js +0 -2
  45. package/dist/connectors/connector.js.map +0 -1
  46. package/dist/connectors/jwt.d.ts +0 -25
  47. package/dist/connectors/jwt.d.ts.map +0 -1
  48. package/dist/connectors/jwt.js +0 -148
  49. package/dist/connectors/jwt.js.map +0 -1
  50. package/dist/errors.d.ts +0 -15
  51. package/dist/errors.d.ts.map +0 -1
  52. package/dist/errors.js +0 -15
  53. package/dist/errors.js.map +0 -1
  54. package/dist/extraction.d.ts +0 -20
  55. package/dist/extraction.d.ts.map +0 -1
  56. package/dist/extraction.js +0 -2
  57. package/dist/extraction.js.map +0 -1
  58. package/dist/index.d.ts +0 -11
  59. package/dist/index.d.ts.map +0 -1
  60. package/dist/index.js +0 -11
  61. package/dist/index.js.map +0 -1
  62. package/dist/permit.d.ts +0 -26
  63. package/dist/permit.d.ts.map +0 -1
  64. package/dist/permit.js +0 -17
  65. package/dist/permit.js.map +0 -1
  66. package/dist/rules.d.ts +0 -47
  67. package/dist/rules.d.ts.map +0 -1
  68. package/dist/rules.js +0 -127
  69. package/dist/rules.js.map +0 -1
  70. package/dist/testing.d.ts +0 -20
  71. package/dist/testing.d.ts.map +0 -1
  72. package/dist/testing.js +0 -22
  73. package/dist/testing.js.map +0 -1
  74. package/dist/trails/auth-verify.d.ts +0 -22
  75. package/dist/trails/auth-verify.d.ts.map +0 -1
  76. package/dist/trails/auth-verify.js +0 -85
  77. package/dist/trails/auth-verify.js.map +0 -1
  78. package/src/__tests__/auth-gate.test.ts +0 -130
  79. package/src/__tests__/auth-provision.test.ts +0 -62
  80. package/src/__tests__/auth-verify.test.ts +0 -278
  81. package/src/__tests__/connector.test.ts +0 -338
  82. package/src/__tests__/permit.test.ts +0 -122
  83. package/src/__tests__/rules.test.ts +0 -239
  84. package/src/__tests__/testing.test.ts +0 -57
  85. package/src/auth-gate.ts +0 -80
  86. package/src/auth-provision.ts +0 -26
  87. package/src/connectors/connector.ts +0 -35
  88. package/tsconfig.json +0 -9
  89. package/tsconfig.tsbuildinfo +0 -1
@@ -1,122 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
-
3
- import type { Permit, PermitExtractionInput } from '../index';
4
- import { getPermit } from '../index';
5
-
6
- describe('Permit type', () => {
7
- test('accepts a valid permit with required fields only', () => {
8
- const permit: Permit = {
9
- id: 'usr_abc123',
10
- scopes: ['user:read', 'user:write'],
11
- };
12
- expect(permit.id).toBe('usr_abc123');
13
- expect(permit.scopes).toEqual(['user:read', 'user:write']);
14
- });
15
-
16
- test('accepts a permit with all optional fields', () => {
17
- const permit: Permit = {
18
- id: 'usr_full',
19
- metadata: { plan: 'pro', provider: 'clerk' },
20
- roles: ['admin', 'editor'],
21
- scopes: ['entity:read'],
22
- tenantId: 'tenant_xyz',
23
- };
24
- expect(permit.roles).toEqual(['admin', 'editor']);
25
- expect(permit.tenantId).toBe('tenant_xyz');
26
- expect(permit.metadata).toEqual({ plan: 'pro', provider: 'clerk' });
27
- });
28
-
29
- test('scopes and roles arrays are readonly', () => {
30
- const permit: Permit = {
31
- id: 'usr_ro',
32
- roles: ['viewer'],
33
- scopes: ['read'],
34
- };
35
- // Structural check: readonly arrays are assignable to readonly string[]
36
- const { scopes } = permit;
37
- const { roles } = permit;
38
- expect(scopes).toEqual(['read']);
39
- expect(roles).toEqual(['viewer']);
40
- });
41
- });
42
-
43
- describe('getPermit()', () => {
44
- test('returns Permit from a context with a permit', () => {
45
- const permit: Permit = { id: 'usr_1', scopes: ['user:read'] };
46
- const ctx = { permit, requestId: 'req-1' };
47
- const result = getPermit(ctx);
48
- expect(result).toEqual(permit);
49
- });
50
-
51
- test('returns undefined when context has no permit', () => {
52
- const ctx = { requestId: 'req-2' };
53
- const result = getPermit(ctx);
54
- expect(result).toBeUndefined();
55
- });
56
-
57
- test('returns undefined when permit is explicitly undefined', () => {
58
- const ctx = { permit: undefined, requestId: 'req-3' };
59
- const result = getPermit(ctx);
60
- expect(result).toBeUndefined();
61
- });
62
-
63
- test('preserves extended permit fields from the auth gate', () => {
64
- const ctx = {
65
- permit: {
66
- id: 'usr_2',
67
- metadata: { plan: 'pro' },
68
- roles: ['admin'],
69
- scopes: ['user:read'],
70
- tenantId: 'tenant-1',
71
- } satisfies Permit,
72
- requestId: 'req-4',
73
- };
74
- const result = getPermit(ctx);
75
- expect(result).toEqual(ctx.permit);
76
- });
77
- });
78
-
79
- describe('PermitExtractionInput', () => {
80
- test('accepts HTTP trailhead extraction', () => {
81
- const input: PermitExtractionInput = {
82
- bearerToken: 'eyJhbGciOiJSUzI1NiJ9.test',
83
- headers: new Headers({
84
- authorization: 'Bearer eyJhbGciOiJSUzI1NiJ9.test',
85
- }),
86
- requestId: 'req-http-1',
87
- trailhead: 'http',
88
- };
89
- expect(input.trailhead).toBe('http');
90
- expect(input.bearerToken).toBeDefined();
91
- });
92
-
93
- test('accepts MCP trailhead extraction', () => {
94
- const input: PermitExtractionInput = {
95
- requestId: 'req-mcp-1',
96
- sessionId: 'mcp-session-abc',
97
- trailhead: 'mcp',
98
- };
99
- expect(input.trailhead).toBe('mcp');
100
- expect(input.sessionId).toBe('mcp-session-abc');
101
- });
102
-
103
- test('accepts CLI trailhead extraction', () => {
104
- const input: PermitExtractionInput = {
105
- bearerToken: 'cli-token-from-keyring',
106
- requestId: 'req-cli-1',
107
- trailhead: 'cli',
108
- };
109
- expect(input.trailhead).toBe('cli');
110
- });
111
-
112
- test('accepts minimal extraction with only required fields', () => {
113
- const input: PermitExtractionInput = {
114
- requestId: 'req-minimal',
115
- trailhead: 'http',
116
- };
117
- expect(input.requestId).toBe('req-minimal');
118
- expect(input.bearerToken).toBeUndefined();
119
- expect(input.sessionId).toBeUndefined();
120
- expect(input.headers).toBeUndefined();
121
- });
122
- });
@@ -1,239 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { trail, Result } from '@ontrails/core';
3
- import { z } from 'zod';
4
-
5
- import {
6
- destroyWithoutPermit,
7
- writeWithoutPermit,
8
- scopeNamingConsistency,
9
- orphanScopeDetection,
10
- validatePermits,
11
- } from '../rules.js';
12
-
13
- // ---------------------------------------------------------------------------
14
- // Helpers
15
- // ---------------------------------------------------------------------------
16
-
17
- const emptyInput = z.object({});
18
- const noopRun = () => Result.ok({});
19
-
20
- // ---------------------------------------------------------------------------
21
- // destroyWithoutPermit
22
- // ---------------------------------------------------------------------------
23
-
24
- describe('destroyWithoutPermit', () => {
25
- test('error when destroy trail has no permit', () => {
26
- const t = trail('user.delete', {
27
- blaze: noopRun,
28
- input: emptyInput,
29
- intent: 'destroy',
30
- });
31
- const diagnostics = destroyWithoutPermit([t]);
32
- expect(diagnostics).toHaveLength(1);
33
- expect(diagnostics[0]).toMatchObject({
34
- message: expect.stringContaining('destroy'),
35
- rule: 'destroyWithoutPermit',
36
- severity: 'error',
37
- trailId: 'user.delete',
38
- });
39
- });
40
-
41
- test('no diagnostic when destroy trail has a scoped permit', () => {
42
- const t = trail('user.delete', {
43
- blaze: noopRun,
44
- input: emptyInput,
45
- intent: 'destroy',
46
- permit: { scopes: ['user:delete'] },
47
- });
48
- const diagnostics = destroyWithoutPermit([t]);
49
- expect(diagnostics).toHaveLength(0);
50
- });
51
-
52
- test('error when destroy trail has permit: public', () => {
53
- const t = trail('user.delete', {
54
- blaze: noopRun,
55
- input: emptyInput,
56
- intent: 'destroy',
57
- permit: 'public',
58
- });
59
- const diagnostics = destroyWithoutPermit([t]);
60
- expect(diagnostics).toHaveLength(1);
61
- expect(diagnostics[0]).toMatchObject({
62
- rule: 'destroyWithoutPermit',
63
- severity: 'error',
64
- trailId: 'user.delete',
65
- });
66
- });
67
- });
68
-
69
- // ---------------------------------------------------------------------------
70
- // writeWithoutPermit
71
- // ---------------------------------------------------------------------------
72
-
73
- describe('writeWithoutPermit', () => {
74
- test('warning when write trail has no permit', () => {
75
- const t = trail('user.create', {
76
- blaze: noopRun,
77
- input: emptyInput,
78
- });
79
- const diagnostics = writeWithoutPermit([t]);
80
- expect(diagnostics).toHaveLength(1);
81
- expect(diagnostics[0]).toMatchObject({
82
- rule: 'writeWithoutPermit',
83
- severity: 'warning',
84
- trailId: 'user.create',
85
- });
86
- });
87
-
88
- test('no warning when write trail has permit: public', () => {
89
- const t = trail('user.create', {
90
- blaze: noopRun,
91
- input: emptyInput,
92
- permit: 'public',
93
- });
94
- const diagnostics = writeWithoutPermit([t]);
95
- expect(diagnostics).toHaveLength(0);
96
- });
97
-
98
- test('warning when trail has no intent (defaults to write)', () => {
99
- const t = trail('user.update', {
100
- blaze: noopRun,
101
- input: emptyInput,
102
- });
103
- // Override intent to undefined to simulate a manually constructed trail
104
- const noIntent = { ...t, intent: undefined } as unknown as ReturnType<
105
- typeof trail
106
- >;
107
- const diagnostics = writeWithoutPermit([noIntent]);
108
- expect(diagnostics).toHaveLength(1);
109
- expect(diagnostics[0]).toMatchObject({
110
- rule: 'writeWithoutPermit',
111
- severity: 'warning',
112
- trailId: 'user.update',
113
- });
114
- });
115
-
116
- test('no diagnostic for read trail without permit', () => {
117
- const t = trail('user.list', {
118
- blaze: noopRun,
119
- input: emptyInput,
120
- intent: 'read',
121
- });
122
- const diagnostics = writeWithoutPermit([t]);
123
- expect(diagnostics).toHaveLength(0);
124
- });
125
- });
126
-
127
- // ---------------------------------------------------------------------------
128
- // scopeNamingConsistency
129
- // ---------------------------------------------------------------------------
130
-
131
- describe('scopeNamingConsistency', () => {
132
- test('scope user:write passes naming check', () => {
133
- const t = trail('user.update', {
134
- blaze: noopRun,
135
- input: emptyInput,
136
- permit: { scopes: ['user:write'] },
137
- });
138
- const diagnostics = scopeNamingConsistency([t]);
139
- expect(diagnostics).toHaveLength(0);
140
- });
141
-
142
- test('warning for scope without colon', () => {
143
- const t = trail('admin.panel', {
144
- blaze: noopRun,
145
- input: emptyInput,
146
- permit: { scopes: ['admin'] },
147
- });
148
- const diagnostics = scopeNamingConsistency([t]);
149
- expect(diagnostics).toHaveLength(1);
150
- expect(diagnostics[0]).toMatchObject({
151
- message: expect.stringContaining('admin'),
152
- rule: 'scopeNamingConsistency',
153
- severity: 'warning',
154
- trailId: 'admin.panel',
155
- });
156
- });
157
- });
158
-
159
- // ---------------------------------------------------------------------------
160
- // orphanScopeDetection
161
- // ---------------------------------------------------------------------------
162
-
163
- describe('orphanScopeDetection', () => {
164
- test('warning for orphan scope (typo)', () => {
165
- const t1 = trail('user.read', {
166
- blaze: noopRun,
167
- input: emptyInput,
168
- permit: { scopes: ['user:read'] },
169
- });
170
- const t2 = trail('user.write', {
171
- blaze: noopRun,
172
- input: emptyInput,
173
- permit: { scopes: ['user:wirte'] },
174
- });
175
- const diagnostics = orphanScopeDetection([t1, t2]);
176
- // Both scopes are unique (appear in only 1 trail each)
177
- expect(diagnostics).toHaveLength(2);
178
- const messages = diagnostics.map((d) => d.message);
179
- expect(messages.some((m) => m.includes('user:wirte'))).toBe(true);
180
- });
181
-
182
- test('no warning for shared scopes', () => {
183
- const t1 = trail('user.read', {
184
- blaze: noopRun,
185
- input: emptyInput,
186
- permit: { scopes: ['user:read'] },
187
- });
188
- const t2 = trail('user.profile', {
189
- blaze: noopRun,
190
- input: emptyInput,
191
- permit: { scopes: ['user:read'] },
192
- });
193
- const diagnostics = orphanScopeDetection([t1, t2]);
194
- expect(diagnostics).toHaveLength(0);
195
- });
196
- });
197
-
198
- // ---------------------------------------------------------------------------
199
- // validatePermits
200
- // ---------------------------------------------------------------------------
201
-
202
- /* oxlint-disable max-statements -- integration test validates all rules fire */
203
- describe('validatePermits', () => {
204
- test('runs all rules and aggregates diagnostics', () => {
205
- const destroyNoPerm = trail('user.delete', {
206
- blaze: noopRun,
207
- input: emptyInput,
208
- intent: 'destroy',
209
- });
210
- const writeNoPerm = trail('user.create', {
211
- blaze: noopRun,
212
- input: emptyInput,
213
- });
214
- const badScope = trail('admin.panel', {
215
- blaze: noopRun,
216
- input: emptyInput,
217
- permit: { scopes: ['admin'] },
218
- });
219
- const orphanScope = trail('analytics.export', {
220
- blaze: noopRun,
221
- input: emptyInput,
222
- permit: { scopes: ['analytics:exportt'] },
223
- });
224
-
225
- const diagnostics = validatePermits([
226
- destroyNoPerm,
227
- writeNoPerm,
228
- badScope,
229
- orphanScope,
230
- ]);
231
-
232
- const rules = diagnostics.map((d) => d.rule);
233
- expect(rules).toContain('destroyWithoutPermit');
234
- expect(rules).toContain('writeWithoutPermit');
235
- expect(rules).toContain('scopeNamingConsistency');
236
- expect(rules).toContain('orphanScopeDetection');
237
- expect(diagnostics.length).toBeGreaterThanOrEqual(4);
238
- });
239
- });
@@ -1,57 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
-
3
- import { mintPermitForTrail, mintTestPermit } from '../testing';
4
-
5
- describe('mintTestPermit()', () => {
6
- test('returns a Permit with the given scopes', () => {
7
- const permit = mintTestPermit({ scopes: ['user:read', 'user:write'] });
8
- expect(permit.scopes).toEqual(['user:read', 'user:write']);
9
- });
10
-
11
- test('generates a unique id when not specified', () => {
12
- const a = mintTestPermit();
13
- const b = mintTestPermit();
14
- expect(a.id).not.toBe(b.id);
15
- });
16
-
17
- test('uses the provided id when specified', () => {
18
- const permit = mintTestPermit({ id: 'custom-id' });
19
- expect(permit.id).toBe('custom-id');
20
- });
21
-
22
- test('returns empty scopes when no options provided', () => {
23
- const permit = mintTestPermit();
24
- expect(permit.scopes).toEqual([]);
25
- });
26
-
27
- test('includes roles when provided', () => {
28
- const permit = mintTestPermit({ roles: ['admin', 'editor'] });
29
- expect(permit.roles).toEqual(['admin', 'editor']);
30
- });
31
-
32
- test('includes tenantId when provided', () => {
33
- const permit = mintTestPermit({ tenantId: 'tenant_abc' });
34
- expect(permit.tenantId).toBe('tenant_abc');
35
- });
36
- });
37
-
38
- describe('mintPermitForTrail()', () => {
39
- test('extracts scopes from trail permit requirement', () => {
40
- const trail = { permit: { scopes: ['entity:read', 'entity:write'] } };
41
- const permit = mintPermitForTrail(trail);
42
- expect(permit).toBeDefined();
43
- expect(permit?.scopes).toEqual(['entity:read', 'entity:write']);
44
- });
45
-
46
- test('returns undefined for public trails', () => {
47
- const trail = { permit: 'public' as const };
48
- const permit = mintPermitForTrail(trail);
49
- expect(permit).toBeUndefined();
50
- });
51
-
52
- test('returns undefined when no permit declared', () => {
53
- const trail = {};
54
- const permit = mintPermitForTrail(trail);
55
- expect(permit).toBeUndefined();
56
- });
57
- });
package/src/auth-gate.ts DELETED
@@ -1,80 +0,0 @@
1
- import { Result } from '@ontrails/core';
2
- import type { Gate } from '@ontrails/core';
3
-
4
- import { PermitError } from './errors.js';
5
- import { getPermit } from './permit.js';
6
-
7
- // ---------------------------------------------------------------------------
8
- // Helpers (defined before callers — no use-before-define)
9
- // ---------------------------------------------------------------------------
10
-
11
- /**
12
- * Returns `true` when the permit requirement means "no enforcement needed."
13
- * Either the trail hasn't declared a permit posture or has explicitly
14
- * opted out with `'public'`.
15
- */
16
- const isPassThrough = (
17
- requirement: unknown
18
- ): requirement is undefined | 'public' =>
19
- requirement === undefined || requirement === 'public';
20
-
21
- /** Returns scopes present in `required` but absent from `held`. */
22
- const findMissing = (
23
- required: readonly string[],
24
- held: readonly string[]
25
- ): readonly string[] => required.filter((s) => !held.includes(s));
26
-
27
- // ---------------------------------------------------------------------------
28
- // Auth gate
29
- // ---------------------------------------------------------------------------
30
-
31
- /**
32
- * A {@link Gate} that enforces permit scopes declared on trails.
33
- *
34
- * The gate reads the trail's `permit` field (a `PermitRequirement`):
35
- *
36
- * - If `permit` is `'public'` or `undefined` the gate passes through.
37
- * - If `permit` has `scopes`, the gate checks that `ctx.permit` contains
38
- * all required scopes. A superset is fine; missing scopes produce a
39
- * `PermitError`.
40
- *
41
- * Because `ctx.cross()` re-enters `executeTrail` (which applies gates),
42
- * this gate automatically re-checks on every invocation in a crossing chain.
43
- * No special crossing-chain handling is needed — it is built into the
44
- * architecture.
45
- */
46
- export const authGate: Gate = {
47
- description: 'Enforces permit scopes declared on trails',
48
- name: 'auth',
49
- wrap: (_trail, impl) => {
50
- const requirement = _trail.permit;
51
-
52
- if (isPassThrough(requirement)) {
53
- return impl;
54
- }
55
-
56
- return (input, ctx) => {
57
- const permit = getPermit(ctx);
58
-
59
- if (!permit) {
60
- return Promise.resolve(
61
- Result.err(new PermitError('No permit provided'))
62
- );
63
- }
64
-
65
- const missing = findMissing(requirement.scopes, permit.scopes);
66
-
67
- if (missing.length > 0) {
68
- return Promise.resolve(
69
- Result.err(
70
- new PermitError(`Missing scopes: ${missing.join(', ')}`, {
71
- context: { missing, required: requirement.scopes },
72
- })
73
- )
74
- );
75
- }
76
-
77
- return Promise.resolve(impl(input, ctx));
78
- };
79
- },
80
- };
@@ -1,26 +0,0 @@
1
- import { Result, provision } from '@ontrails/core';
2
-
3
- import type { AuthConnector } from './connectors/connector.js';
4
-
5
- /**
6
- * Auth provision — manages the auth connector lifecycle.
7
- *
8
- * The v1 factory returns a no-op connector that always succeeds (null permit).
9
- * Real connector configuration will come through `ProvisionSpec.config`
10
- * (TRL-91). The mock factory provides a synthetic connector that always
11
- * succeeds.
12
- */
13
- export const authProvision = provision<AuthConnector>('auth', {
14
- create: (_svc) =>
15
- Result.ok({
16
- // oxlint-disable-next-line require-await -- stub connector satisfies async interface
17
- authenticate: async () => Result.ok(null),
18
- } satisfies AuthConnector),
19
- description: 'Authentication connector',
20
- meta: { category: 'infrastructure' },
21
- mock: () =>
22
- ({
23
- // oxlint-disable-next-line require-await -- mock connector satisfies async interface
24
- authenticate: async () => Result.ok(null),
25
- }) satisfies AuthConnector,
26
- });
@@ -1,35 +0,0 @@
1
- import type { Result } from '@ontrails/core';
2
-
3
- import type { PermitExtractionInput } from '../extraction.js';
4
- import type { Permit } from '../permit.js';
5
-
6
- /**
7
- * @deprecated Use {@link PermitExtractionInput} instead. Kept as an alias
8
- * for backward compatibility during migration.
9
- */
10
- export type AuthCredentials = PermitExtractionInput;
11
-
12
- /** Errors from auth connectors. */
13
- export interface AuthError {
14
- readonly code:
15
- | 'expired_token'
16
- | 'insufficient_scope'
17
- | 'invalid_token'
18
- | 'missing_credentials';
19
- readonly message: string;
20
- }
21
-
22
- /**
23
- * Auth connector port. Given extraction input, produce a permit or an error.
24
- *
25
- * The connector receives the full {@link PermitExtractionInput} — trailhead,
26
- * headers, requestId, and credential fields — so it can make richer
27
- * decisions (e.g., rate-limit by trailhead or correlate via requestId).
28
- *
29
- * Deliberately narrow — no session management, no token refresh.
30
- */
31
- export interface AuthConnector {
32
- readonly authenticate: (
33
- input: PermitExtractionInput
34
- ) => Promise<Result<Permit | null, AuthError>>;
35
- }
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": "src"
6
- },
7
- "include": ["src"],
8
- "exclude": ["**/__tests__/**", "**/*.test.ts", "dist"]
9
- }
@@ -1 +0,0 @@
1
- {"root":["./src/auth-gate.ts","./src/auth-provision.ts","./src/errors.ts","./src/extraction.ts","./src/index.ts","./src/permit.ts","./src/rules.ts","./src/testing.ts","./src/connectors/connector.ts","./src/connectors/jwt.ts","./src/trails/auth-verify.ts"],"version":"5.9.3"}