@ontrails/permits 1.0.0-beta.15 → 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 (70) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +30 -22
  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 +81 -18
  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/trails/auth-verify.ts +11 -13
  12. package/.turbo/turbo-build.log +0 -1
  13. package/.turbo/turbo-lint.log +0 -3
  14. package/.turbo/turbo-typecheck.log +0 -1
  15. package/dist/auth-layer.d.ts +0 -18
  16. package/dist/auth-layer.d.ts.map +0 -1
  17. package/dist/auth-layer.js +0 -56
  18. package/dist/auth-layer.js.map +0 -1
  19. package/dist/auth-resource.d.ts +0 -11
  20. package/dist/auth-resource.d.ts.map +0 -1
  21. package/dist/auth-resource.js +0 -22
  22. package/dist/auth-resource.js.map +0 -1
  23. package/dist/connectors/connector.d.ts +0 -26
  24. package/dist/connectors/connector.d.ts.map +0 -1
  25. package/dist/connectors/connector.js +0 -2
  26. package/dist/connectors/connector.js.map +0 -1
  27. package/dist/connectors/jwt.d.ts +0 -25
  28. package/dist/connectors/jwt.d.ts.map +0 -1
  29. package/dist/connectors/jwt.js +0 -148
  30. package/dist/connectors/jwt.js.map +0 -1
  31. package/dist/errors.d.ts +0 -15
  32. package/dist/errors.d.ts.map +0 -1
  33. package/dist/errors.js +0 -15
  34. package/dist/errors.js.map +0 -1
  35. package/dist/extraction.d.ts +0 -20
  36. package/dist/extraction.d.ts.map +0 -1
  37. package/dist/extraction.js +0 -2
  38. package/dist/extraction.js.map +0 -1
  39. package/dist/index.d.ts +0 -11
  40. package/dist/index.d.ts.map +0 -1
  41. package/dist/index.js +0 -11
  42. package/dist/index.js.map +0 -1
  43. package/dist/permit.d.ts +0 -26
  44. package/dist/permit.d.ts.map +0 -1
  45. package/dist/permit.js +0 -17
  46. package/dist/permit.js.map +0 -1
  47. package/dist/rules.d.ts +0 -47
  48. package/dist/rules.d.ts.map +0 -1
  49. package/dist/rules.js +0 -127
  50. package/dist/rules.js.map +0 -1
  51. package/dist/testing.d.ts +0 -20
  52. package/dist/testing.d.ts.map +0 -1
  53. package/dist/testing.js +0 -22
  54. package/dist/testing.js.map +0 -1
  55. package/dist/trails/auth-verify.d.ts +0 -22
  56. package/dist/trails/auth-verify.d.ts.map +0 -1
  57. package/dist/trails/auth-verify.js +0 -85
  58. package/dist/trails/auth-verify.js.map +0 -1
  59. package/src/__tests__/auth-layer.test.ts +0 -130
  60. package/src/__tests__/auth-resource.test.ts +0 -62
  61. package/src/__tests__/auth-verify.test.ts +0 -278
  62. package/src/__tests__/connector.test.ts +0 -338
  63. package/src/__tests__/permit.test.ts +0 -122
  64. package/src/__tests__/rules.test.ts +0 -239
  65. package/src/__tests__/testing.test.ts +0 -57
  66. package/src/auth-layer.ts +0 -80
  67. package/src/connectors/connector.ts +0 -35
  68. package/tsconfig.json +0 -9
  69. package/tsconfig.tests.json +0 -10
  70. package/tsconfig.tsbuildinfo +0 -1
@@ -1,57 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
-
3
- import { createPermitForTrail, createTestPermit } from '../testing';
4
-
5
- describe('createTestPermit()', () => {
6
- test('returns a Permit with the given scopes', () => {
7
- const permit = createTestPermit({ 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 = createTestPermit();
13
- const b = createTestPermit();
14
- expect(a.id).not.toBe(b.id);
15
- });
16
-
17
- test('uses the provided id when specified', () => {
18
- const permit = createTestPermit({ id: 'custom-id' });
19
- expect(permit.id).toBe('custom-id');
20
- });
21
-
22
- test('returns empty scopes when no options provided', () => {
23
- const permit = createTestPermit();
24
- expect(permit.scopes).toEqual([]);
25
- });
26
-
27
- test('includes roles when provided', () => {
28
- const permit = createTestPermit({ roles: ['admin', 'editor'] });
29
- expect(permit.roles).toEqual(['admin', 'editor']);
30
- });
31
-
32
- test('includes tenantId when provided', () => {
33
- const permit = createTestPermit({ tenantId: 'tenant_abc' });
34
- expect(permit.tenantId).toBe('tenant_abc');
35
- });
36
- });
37
-
38
- describe('createPermitForTrail()', () => {
39
- test('extracts scopes from trail permit requirement', () => {
40
- const trail = { permit: { scopes: ['entity:read', 'entity:write'] } };
41
- const permit = createPermitForTrail(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 = createPermitForTrail(trail);
49
- expect(permit).toBeUndefined();
50
- });
51
-
52
- test('returns undefined when no permit declared', () => {
53
- const trail = {};
54
- const permit = createPermitForTrail(trail);
55
- expect(permit).toBeUndefined();
56
- });
57
- });
package/src/auth-layer.ts DELETED
@@ -1,80 +0,0 @@
1
- import { Result } from '@ontrails/core';
2
- import type { Layer } 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 layer
29
- // ---------------------------------------------------------------------------
30
-
31
- /**
32
- * A {@link Layer} that enforces permit scopes declared on trails.
33
- *
34
- * The layer reads the trail's `permit` field (a `PermitRequirement`):
35
- *
36
- * - If `permit` is `'public'` or `undefined` the layer passes through.
37
- * - If `permit` has `scopes`, the layer 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 layers),
42
- * this layer 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 authLayer: Layer = {
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,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,10 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "noEmit": true,
5
- "rootDir": "./src",
6
- "types": ["bun"]
7
- },
8
- "include": ["src/**/*.test.ts", "src/__tests__/**/*.ts"],
9
- "exclude": []
10
- }
@@ -1 +0,0 @@
1
- {"root":["./src/auth-layer.ts","./src/auth-resource.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"}