@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.
- package/CHANGELOG.md +69 -0
- package/README.md +30 -22
- package/package.json +12 -3
- package/src/adapters/adapter.ts +41 -0
- package/src/{connectors → adapters}/jwt.ts +148 -21
- package/src/auth-resource.ts +81 -18
- package/src/boundary.ts +200 -0
- package/src/errors.ts +1 -18
- package/src/extraction.ts +22 -16
- package/src/index.ts +22 -10
- package/src/trails/auth-verify.ts +11 -13
- package/.turbo/turbo-build.log +0 -1
- package/.turbo/turbo-lint.log +0 -3
- package/.turbo/turbo-typecheck.log +0 -1
- package/dist/auth-layer.d.ts +0 -18
- package/dist/auth-layer.d.ts.map +0 -1
- package/dist/auth-layer.js +0 -56
- package/dist/auth-layer.js.map +0 -1
- package/dist/auth-resource.d.ts +0 -11
- package/dist/auth-resource.d.ts.map +0 -1
- package/dist/auth-resource.js +0 -22
- package/dist/auth-resource.js.map +0 -1
- package/dist/connectors/connector.d.ts +0 -26
- package/dist/connectors/connector.d.ts.map +0 -1
- package/dist/connectors/connector.js +0 -2
- package/dist/connectors/connector.js.map +0 -1
- package/dist/connectors/jwt.d.ts +0 -25
- package/dist/connectors/jwt.d.ts.map +0 -1
- package/dist/connectors/jwt.js +0 -148
- package/dist/connectors/jwt.js.map +0 -1
- package/dist/errors.d.ts +0 -15
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -15
- package/dist/errors.js.map +0 -1
- package/dist/extraction.d.ts +0 -20
- package/dist/extraction.d.ts.map +0 -1
- package/dist/extraction.js +0 -2
- package/dist/extraction.js.map +0 -1
- package/dist/index.d.ts +0 -11
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -11
- package/dist/index.js.map +0 -1
- package/dist/permit.d.ts +0 -26
- package/dist/permit.d.ts.map +0 -1
- package/dist/permit.js +0 -17
- package/dist/permit.js.map +0 -1
- package/dist/rules.d.ts +0 -47
- package/dist/rules.d.ts.map +0 -1
- package/dist/rules.js +0 -127
- package/dist/rules.js.map +0 -1
- package/dist/testing.d.ts +0 -20
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -22
- package/dist/testing.js.map +0 -1
- package/dist/trails/auth-verify.d.ts +0 -22
- package/dist/trails/auth-verify.d.ts.map +0 -1
- package/dist/trails/auth-verify.js +0 -85
- package/dist/trails/auth-verify.js.map +0 -1
- package/src/__tests__/auth-layer.test.ts +0 -130
- package/src/__tests__/auth-resource.test.ts +0 -62
- package/src/__tests__/auth-verify.test.ts +0 -278
- package/src/__tests__/connector.test.ts +0 -338
- package/src/__tests__/permit.test.ts +0 -122
- package/src/__tests__/rules.test.ts +0 -239
- package/src/__tests__/testing.test.ts +0 -57
- package/src/auth-layer.ts +0 -80
- package/src/connectors/connector.ts +0 -35
- package/tsconfig.json +0 -9
- package/tsconfig.tests.json +0 -10
- 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
package/tsconfig.tests.json
DELETED
package/tsconfig.tsbuildinfo
DELETED
|
@@ -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"}
|