@toa.io/extensions.exposition 1.0.0-alpha.251 → 1.0.0-alpha.253
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/components/identity.bans/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/manifest.toa.yaml +16 -0
- package/components/identity.basic/operations/delete.d.ts +7 -0
- package/components/identity.basic/operations/delete.js +11 -0
- package/components/identity.basic/operations/delete.js.map +1 -0
- package/components/identity.basic/operations/info.d.ts +10 -0
- package/components/identity.basic/operations/info.js +11 -0
- package/components/identity.basic/operations/info.js.map +1 -0
- package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/operations/types.d.ts +2 -1
- package/components/identity.basic/source/delete.ts +15 -0
- package/components/identity.basic/source/info.ts +19 -0
- package/components/identity.basic/source/types.ts +2 -1
- package/components/identity.credentials/manifest.toa.yaml +57 -0
- package/components/identity.credentials/operations/list.d.ts +51 -0
- package/components/identity.credentials/operations/list.js +32 -0
- package/components/identity.credentials/operations/list.js.map +1 -0
- package/components/identity.credentials/operations/tsconfig.tsbuildinfo +1 -0
- package/components/identity.credentials/source/list.test.ts +47 -0
- package/components/identity.credentials/source/list.ts +87 -0
- package/components/identity.credentials/tsconfig.json +7 -0
- package/components/identity.federation/manifest.toa.yaml +35 -1
- package/components/identity.federation/operations/authenticate.js +1 -1
- package/components/identity.federation/operations/authenticate.js.map +1 -1
- package/components/identity.federation/operations/delete.d.ts +8 -0
- package/components/identity.federation/operations/delete.js +11 -0
- package/components/identity.federation/operations/delete.js.map +1 -0
- package/components/identity.federation/operations/incept.js +14 -4
- package/components/identity.federation/operations/incept.js.map +1 -1
- package/components/identity.federation/operations/list.d.ts +7 -0
- package/components/identity.federation/operations/list.js +18 -0
- package/components/identity.federation/operations/list.js.map +1 -0
- package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/operations/types/context.d.ts +5 -5
- package/components/identity.federation/operations/types/entity.d.ts +2 -0
- package/components/identity.federation/source/authenticate.ts +1 -1
- package/components/identity.federation/source/delete.ts +16 -0
- package/components/identity.federation/source/incept.ts +18 -4
- package/components/identity.federation/source/list.test.ts +23 -0
- package/components/identity.federation/source/list.ts +23 -0
- package/components/identity.federation/source/types/context.ts +5 -6
- package/components/identity.federation/source/types/entity.ts +2 -0
- package/components/identity.keys/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.otp/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.passkeys/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -1
- package/documentation/components.md +3 -0
- package/documentation/credentials.md +85 -0
- package/documentation/identity.md +3 -0
- package/documentation/passkeys.md +1 -0
- package/features/credentials.feature +106 -0
- package/features/steps/Database.ts +6 -2
- package/package.json +6 -5
- package/readme.md +19 -0
- package/source/HTTP/Server.ts +1 -0
- package/transpiled/HTTP/Server.js +1 -0
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/tsconfig.tsbuildinfo +1 -1
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { JWTPayload } from 'jose';
|
|
2
|
-
import type { Call, Observation, Query, telemetry } from '@toa.io/types';
|
|
2
|
+
import type { Call, Observation, Query, telemetry, Transition } from '@toa.io/types';
|
|
3
3
|
import type { Entity } from './entity';
|
|
4
4
|
import type { Configuration } from './configuration';
|
|
5
5
|
export interface Context {
|
|
6
6
|
local: {
|
|
7
7
|
observe: Observation<Entity>;
|
|
8
|
+
enumerate: Observation<Entity[], never, Entity>;
|
|
9
|
+
terminate: Transition<void, void, Entity>;
|
|
8
10
|
transit: Call<TransitOutput, TransitInput>;
|
|
9
|
-
ensure: Call<
|
|
11
|
+
ensure: Call<Entity>;
|
|
10
12
|
decode: Call<JWTPayload, string>;
|
|
11
13
|
};
|
|
12
14
|
remote: {
|
|
@@ -23,13 +25,11 @@ export interface TransitInput {
|
|
|
23
25
|
readonly authority: string;
|
|
24
26
|
readonly iss: string;
|
|
25
27
|
readonly sub: string;
|
|
28
|
+
readonly identity?: string;
|
|
26
29
|
}
|
|
27
30
|
export interface TransitOutput {
|
|
28
31
|
id: string;
|
|
29
32
|
}
|
|
30
|
-
export interface EnsureOutput {
|
|
31
|
-
id: string;
|
|
32
|
-
}
|
|
33
33
|
interface IdentityTokensRevokeInput {
|
|
34
34
|
query: Query;
|
|
35
35
|
}
|
|
@@ -34,7 +34,7 @@ export async function effect ({ scheme, authority, credentials }: Input, context
|
|
|
34
34
|
if (identity instanceof Error)
|
|
35
35
|
return identity
|
|
36
36
|
|
|
37
|
-
return { identity: { id: identity.id, claims } }
|
|
37
|
+
return { identity: { id: identity.identity ?? identity.id, claims } }
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const ERR_NOT_FOUND = new Err('NOT_FOUND')
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Context } from './types'
|
|
2
|
+
|
|
3
|
+
export async function effect ({ authority, identity, id }: Input, context: Context): Promise<void | null> {
|
|
4
|
+
const object = await context.local.observe({ query: { id } })
|
|
5
|
+
|
|
6
|
+
if (object === null || object.authority !== authority || (object.identity ?? object.id) !== identity)
|
|
7
|
+
return null
|
|
8
|
+
|
|
9
|
+
return await context.local.terminate({ query: { id } })
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface Input {
|
|
13
|
+
authority: string
|
|
14
|
+
identity: string
|
|
15
|
+
id: string
|
|
16
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Err } from 'error-value'
|
|
1
2
|
import { decode, exchange, type Ctx } from './lib'
|
|
2
3
|
import type { Request } from '@toa.io/types'
|
|
3
4
|
import type { Context, TransitInput, Scheme } from './types'
|
|
@@ -16,12 +17,23 @@ export async function effect (input: Input, context: Context): Promise<Output |
|
|
|
16
17
|
return claims
|
|
17
18
|
|
|
18
19
|
const { iss, sub } = claims
|
|
19
|
-
const request: Request<TransitInput> = { input: { authority: input.authority, iss, sub } }
|
|
20
20
|
|
|
21
|
-
if (input.id
|
|
22
|
-
request
|
|
21
|
+
if (input.id === undefined) {
|
|
22
|
+
const request: Request<TransitInput> = { input: { authority: input.authority, iss, sub } }
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
return await context.local.transit(request)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const existent = await context.local.observe({
|
|
28
|
+
query: { criteria: `authority==${input.authority};iss==${iss};sub==${sub}` }
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
if (existent !== null)
|
|
32
|
+
return (existent.identity ?? existent.id) === input.id ? { id: input.id } : ERR_EXISTS
|
|
33
|
+
|
|
34
|
+
return await context.local.transit({
|
|
35
|
+
input: { authority: input.authority, iss, sub, identity: input.id }
|
|
36
|
+
})
|
|
25
37
|
}
|
|
26
38
|
|
|
27
39
|
export interface Input {
|
|
@@ -34,3 +46,5 @@ export interface Input {
|
|
|
34
46
|
export interface Output {
|
|
35
47
|
id: string
|
|
36
48
|
}
|
|
49
|
+
|
|
50
|
+
const ERR_EXISTS = new Err('EXISTS', 'Federation credentials are associated with another Identity')
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { computation } from './list'
|
|
2
|
+
|
|
3
|
+
it('lists indexed credentials and a legacy associated credential', async () => {
|
|
4
|
+
const current = { id: 'credential', authority: 'nex', identity: 'identity', iss: 'apple', sub: '1', _created: 2 }
|
|
5
|
+
const legacy = { id: 'identity', authority: 'nex', iss: 'google', sub: '2', _created: 1 }
|
|
6
|
+
|
|
7
|
+
const context = {
|
|
8
|
+
local: {
|
|
9
|
+
enumerate: jest.fn(async () => [current]),
|
|
10
|
+
observe: jest.fn(async () => legacy)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
await expect(computation({ authority: 'nex', identity: 'identity' }, context as never))
|
|
15
|
+
.resolves.toEqual([current, legacy])
|
|
16
|
+
expect(context.local.enumerate).toHaveBeenCalledWith({
|
|
17
|
+
query: {
|
|
18
|
+
criteria: 'authority==nex;identity==identity',
|
|
19
|
+
projection: ['iss'],
|
|
20
|
+
sort: ['_created:desc']
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Context, Entity } from './types'
|
|
2
|
+
|
|
3
|
+
export async function computation ({ authority, identity }: Input, context: Context): Promise<Entity[]> {
|
|
4
|
+
const objects = await context.local.enumerate({
|
|
5
|
+
query: {
|
|
6
|
+
criteria: `authority==${authority};identity==${identity}`,
|
|
7
|
+
projection: ['iss'],
|
|
8
|
+
sort: ['_created:desc']
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const legacy = await context.local.observe({ query: { id: identity } })
|
|
13
|
+
|
|
14
|
+
if (legacy !== null && legacy.authority === authority && legacy.identity === undefined)
|
|
15
|
+
objects.push(legacy)
|
|
16
|
+
|
|
17
|
+
return objects.sort((a, b) => b._created - a._created)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface Input {
|
|
21
|
+
authority: string
|
|
22
|
+
identity: string
|
|
23
|
+
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { JWTPayload } from 'jose'
|
|
2
|
-
import type { Call, Observation, Query, telemetry } from '@toa.io/types'
|
|
2
|
+
import type { Call, Observation, Query, telemetry, Transition } from '@toa.io/types'
|
|
3
3
|
import type { Entity } from './entity'
|
|
4
4
|
import type { Configuration } from './configuration'
|
|
5
5
|
|
|
6
6
|
export interface Context {
|
|
7
7
|
local: {
|
|
8
8
|
observe: Observation<Entity>
|
|
9
|
+
enumerate: Observation<Entity[], never, Entity>
|
|
10
|
+
terminate: Transition<void, void, Entity>
|
|
9
11
|
transit: Call<TransitOutput, TransitInput>
|
|
10
|
-
ensure: Call<
|
|
12
|
+
ensure: Call<Entity>
|
|
11
13
|
decode: Call<JWTPayload, string>
|
|
12
14
|
}
|
|
13
15
|
remote: {
|
|
@@ -25,16 +27,13 @@ export interface TransitInput {
|
|
|
25
27
|
readonly authority: string
|
|
26
28
|
readonly iss: string
|
|
27
29
|
readonly sub: string
|
|
30
|
+
readonly identity?: string
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
export interface TransitOutput {
|
|
31
34
|
id: string
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
export interface EnsureOutput {
|
|
35
|
-
id: string
|
|
36
|
-
}
|
|
37
|
-
|
|
38
37
|
interface IdentityTokensRevokeInput {
|
|
39
38
|
query: Query
|
|
40
39
|
}
|