@owlmeans/server-auth-identity 0.1.18-rc.2 → 0.1.18-rc.21
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/README.md +7 -6
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/server-auth-identity/SKILL.md +165 -80
- package/build/consts.d.ts +3 -0
- package/build/consts.d.ts.map +1 -1
- package/build/consts.js +5 -0
- package/build/consts.js.map +1 -1
- package/build/helper.d.ts.map +1 -1
- package/build/helper.js +7 -1
- package/build/helper.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/resolver.d.ts +3 -0
- package/build/resolver.d.ts.map +1 -0
- package/build/resolver.js +133 -0
- package/build/resolver.js.map +1 -0
- package/build/resource.d.ts +11 -1
- package/build/resource.d.ts.map +1 -1
- package/build/resource.js +30 -4
- package/build/resource.js.map +1 -1
- package/build/service.d.ts.map +1 -1
- package/build/service.js +115 -25
- package/build/service.js.map +1 -1
- package/build/types.d.ts +41 -3
- package/build/types.d.ts.map +1 -1
- package/package.json +10 -9
- package/src/consts.ts +6 -0
- package/src/helper.ts +7 -1
- package/src/index.ts +1 -0
- package/src/resolver.ts +165 -0
- package/src/resource.ts +36 -6
- package/src/service.ts +130 -28
- package/src/types.ts +43 -3
- package/tests/linking.spec.ts +202 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
|
package/build/resource.d.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import type { IdentityAccountResource, IdentityProfileResource, IdentityCredentialsResource } from './types.js';
|
|
1
|
+
import type { IdentityAccountResource, IdentityProfileResource, IdentityCredentialsResource, OrgEntityResource } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The organization-entity registry.
|
|
4
|
+
*
|
|
5
|
+
* Both unique indexes are load-bearing. `slug` is what a rename writes, so the index is the only
|
|
6
|
+
* thing standing between two organizations and the same public name; `iamKey` is quoted by systems
|
|
7
|
+
* that were told it once and never asked again, so a duplicate there would silently hand one
|
|
8
|
+
* organization another's realm. `formerSlugs` is indexed but NOT unique-scoped as a set — a retired
|
|
9
|
+
* slug must stay findable, and uniqueness against it is enforced when a rename is applied.
|
|
10
|
+
*/
|
|
11
|
+
export declare const makeOrgEntityResource: (dbAlias?: string) => OrgEntityResource;
|
|
2
12
|
export declare const makeIdentityAccountResource: (dbAlias?: string) => IdentityAccountResource;
|
|
3
13
|
export declare const makeIdentityProfileResource: (dbAlias?: string) => IdentityProfileResource;
|
|
4
14
|
export declare const makeIdentityCredentialsResource: (dbAlias?: string) => IdentityCredentialsResource;
|
package/build/resource.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,uBAAuB,EAAmB,uBAAuB,EAAuB,2BAA2B,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,uBAAuB,EAAmB,uBAAuB,EAAuB,2BAA2B,EAAa,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAOpM;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,aAAc,MAAM,KAAG,iBAQxD,CAAA;AAED,eAAO,MAAM,2BAA2B,aAAc,MAAM,KAAG,uBAkB9D,CAAA;AAED,eAAO,MAAM,2BAA2B,aAAc,MAAM,KAAG,uBAe9D,CAAA;AAED,eAAO,MAAM,+BAA+B,aAAc,MAAM,KAAG,2BAOlE,CAAA"}
|
package/build/resource.js
CHANGED
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
import { makeMongoResource } from '@owlmeans/mongo-resource';
|
|
2
|
-
import { AUTH_IDENTITY_ACCOUNT, AUTH_IDENTITY_PROFILE, AUTH_IDENTITY_CREDENTIALS, AUTH_IDENTITY_ACCOUNT_COLLECTION, AUTH_IDENTITY_PROFILE_COLLECTION, AUTH_IDENTITY_CREDENTIALS_COLLECTION } from './consts.js';
|
|
2
|
+
import { AUTH_IDENTITY_ACCOUNT, AUTH_IDENTITY_PROFILE, AUTH_IDENTITY_CREDENTIALS, AUTH_IDENTITY_ORG_ENTITY, AUTH_IDENTITY_ACCOUNT_COLLECTION, AUTH_IDENTITY_PROFILE_COLLECTION, AUTH_IDENTITY_CREDENTIALS_COLLECTION, AUTH_IDENTITY_ORG_ENTITY_COLLECTION } from './consts.js';
|
|
3
|
+
/**
|
|
4
|
+
* The organization-entity registry.
|
|
5
|
+
*
|
|
6
|
+
* Both unique indexes are load-bearing. `slug` is what a rename writes, so the index is the only
|
|
7
|
+
* thing standing between two organizations and the same public name; `iamKey` is quoted by systems
|
|
8
|
+
* that were told it once and never asked again, so a duplicate there would silently hand one
|
|
9
|
+
* organization another's realm. `formerSlugs` is indexed but NOT unique-scoped as a set — a retired
|
|
10
|
+
* slug must stay findable, and uniqueness against it is enforced when a rename is applied.
|
|
11
|
+
*/
|
|
12
|
+
export const makeOrgEntityResource = (dbAlias) => {
|
|
13
|
+
const resource = makeMongoResource(AUTH_IDENTITY_ORG_ENTITY, dbAlias, undefined, AUTH_IDENTITY_ORG_ENTITY_COLLECTION);
|
|
14
|
+
resource.index('slug', { slug: 1 }, { unique: true });
|
|
15
|
+
resource.index('iamKey', { iamKey: 1 }, { unique: true });
|
|
16
|
+
resource.index('formerSlugs', { formerSlugs: 1 });
|
|
17
|
+
return resource;
|
|
18
|
+
};
|
|
3
19
|
export const makeIdentityAccountResource = (dbAlias) => {
|
|
4
|
-
const resource = makeMongoResource(AUTH_IDENTITY_ACCOUNT, dbAlias, undefined,
|
|
20
|
+
const resource = makeMongoResource(AUTH_IDENTITY_ACCOUNT, dbAlias, undefined, AUTH_IDENTITY_ACCOUNT_COLLECTION);
|
|
5
21
|
resource.index('credential', { credential: 1 }, { unique: true });
|
|
6
22
|
resource.index('entityId', { entityId: 1 });
|
|
7
23
|
resource.index('secret', { secret: 1 }, { unique: true, sparse: true });
|
|
24
|
+
/**
|
|
25
|
+
* The account's login name — an email, for every provider shipped today.
|
|
26
|
+
*
|
|
27
|
+
* Indexed because `linkProfile` reads it on every registration: a person signing in by a second
|
|
28
|
+
* method must land on the identity they already have, not a new one. NOT unique — the same
|
|
29
|
+
* address legitimately appears twice, once for the platform account and once for an
|
|
30
|
+
* organization's END USER record (`inviteUser`), and those are different people-shaped rows for
|
|
31
|
+
* different audiences. The two are told apart by the profile, never by the account.
|
|
32
|
+
*/
|
|
33
|
+
resource.index('name', { name: 1 });
|
|
8
34
|
return resource;
|
|
9
35
|
};
|
|
10
36
|
export const makeIdentityProfileResource = (dbAlias) => {
|
|
11
|
-
const resource = makeMongoResource(AUTH_IDENTITY_PROFILE, dbAlias, undefined,
|
|
37
|
+
const resource = makeMongoResource(AUTH_IDENTITY_PROFILE, dbAlias, undefined, AUTH_IDENTITY_PROFILE_COLLECTION);
|
|
12
38
|
/**
|
|
13
39
|
* The account's mongo id — the ONLY ObjectId reference in the identity trio.
|
|
14
40
|
* `profileId` is a composite key (`"{type}:{accountId}"`), `entityId` is the Base58
|
|
@@ -22,7 +48,7 @@ export const makeIdentityProfileResource = (dbAlias) => {
|
|
|
22
48
|
return resource;
|
|
23
49
|
};
|
|
24
50
|
export const makeIdentityCredentialsResource = (dbAlias) => {
|
|
25
|
-
const resource = makeMongoResource(AUTH_IDENTITY_CREDENTIALS, dbAlias, undefined,
|
|
51
|
+
const resource = makeMongoResource(AUTH_IDENTITY_CREDENTIALS, dbAlias, undefined, AUTH_IDENTITY_CREDENTIALS_COLLECTION);
|
|
26
52
|
resource.index('provider', { type: 1, userId: 1, credential: 1 }, { unique: true });
|
|
27
53
|
resource.index('profileId', { profileId: 1 });
|
|
28
54
|
return resource;
|
package/build/resource.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5D,OAAO,EACL,qBAAqB,EAAE,qBAAqB,EAAE,yBAAyB,
|
|
1
|
+
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"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"}
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA8F,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAmBpJ,eAAO,MAAM,0BAA0B,QAAO,sBA8Q7C,CAAA"}
|
package/build/service.js
CHANGED
|
@@ -1,29 +1,75 @@
|
|
|
1
1
|
import { appendContextual } from '@owlmeans/context';
|
|
2
2
|
import { ALL_SCOPES, AuthRole } from '@owlmeans/auth';
|
|
3
3
|
import { createIdOfLength, IdStyle } from '@owlmeans/basic-ids';
|
|
4
|
-
import {
|
|
4
|
+
import { ENTITY_RESOLVER } from '@owlmeans/auth-common';
|
|
5
|
+
import { AUTH_IDENTITY_ACCOUNT, AUTH_IDENTITY_PROFILE, AUTH_IDENTITY_CREDENTIALS, AUTH_IDENTITY_LINKING, AUTH_IDENTITY_ORG_ENTITY, LOGIN_SERVICE_PREFIX, EXTERNAL_KEY_DELIMITER } from './consts.js';
|
|
5
6
|
const MAX_SLUG_RETRIES = 5;
|
|
6
7
|
// Stable external login key: "{type}:{service}:{providerSub}"
|
|
7
8
|
const externalKey = (details) => [details.type, details.service, details.userId].join(EXTERNAL_KEY_DELIMITER);
|
|
8
9
|
// Login-service credential stored on profile and credentials: "service:{type}:{service}"
|
|
9
10
|
const loginService = (details) => [LOGIN_SERVICE_PREFIX, details.type, details.service].join(EXTERNAL_KEY_DELIMITER);
|
|
10
11
|
export const makeIdentityLinkingService = () => {
|
|
12
|
+
/**
|
|
13
|
+
* The wire value for a stored entity id.
|
|
14
|
+
*
|
|
15
|
+
* Records key on the id; everything this service hands back is an auth payload, and payloads
|
|
16
|
+
* carry the slug. An id that no longer resolves yields undefined rather than leaking the raw
|
|
17
|
+
* id onto the wire, where a consumer would mistake it for a slug and compose names from it.
|
|
18
|
+
*/
|
|
19
|
+
const slugOf = async (entityId) => {
|
|
20
|
+
if (entityId == null || entityId === '')
|
|
21
|
+
return undefined;
|
|
22
|
+
const ctx = service.ctx;
|
|
23
|
+
const entity = await ctx.service(ENTITY_RESOLVER).byId(entityId);
|
|
24
|
+
return entity?.slug;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The platform identity this person already has, if any.
|
|
28
|
+
*
|
|
29
|
+
* One human, one email, one profile — whichever way they sign in. Every provider that reaches
|
|
30
|
+
* `linkProfile` establishes the email first (Google asserts a verified address, the OTP flow
|
|
31
|
+
* proves possession of it, the supervisor key is a full-trust developer credential), so the
|
|
32
|
+
* name is the identity and a second method is a second CREDENTIAL on it, never a second person.
|
|
33
|
+
* Without this the platform minted a whole new organization per method: the same address signed
|
|
34
|
+
* in by Google and by key ended up in two entities, and each could see only the projects the
|
|
35
|
+
* other had not created.
|
|
36
|
+
*
|
|
37
|
+
* Two rows can carry one address, and only one of them is a platform login. `inviteUser`
|
|
38
|
+
* (`@owlmeans/iam-integrated`) writes an END USER record for the same person — the identity the
|
|
39
|
+
* GENERATED application authenticates, deliberately kept apart from the platform credential.
|
|
40
|
+
* Those rows carry no login service, which is what tells the two apart here: this service is
|
|
41
|
+
* the only writer of `credential = "service:{type}:{service}"`, so a profile that has one is a
|
|
42
|
+
* platform login and a profile that has none is somebody's end user.
|
|
43
|
+
*/
|
|
44
|
+
const findPlatformIdentity = async (username) => {
|
|
45
|
+
const name = username.trim();
|
|
46
|
+
if (name === '')
|
|
47
|
+
return null;
|
|
48
|
+
const ctx = service.ctx;
|
|
49
|
+
const accountResource = ctx.resource(AUTH_IDENTITY_ACCOUNT);
|
|
50
|
+
const profileResource = ctx.resource(AUTH_IDENTITY_PROFILE);
|
|
51
|
+
const { items: accounts } = await accountResource.list({ name });
|
|
52
|
+
for (const account of accounts) {
|
|
53
|
+
const { items: profiles } = await profileResource.list({ userId: account.id });
|
|
54
|
+
const platform = profiles.find(profile => profile.credential?.startsWith(`${LOGIN_SERVICE_PREFIX}${EXTERNAL_KEY_DELIMITER}`) === true);
|
|
55
|
+
if (platform != null)
|
|
56
|
+
return platform;
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
};
|
|
11
60
|
const service = appendContextual(AUTH_IDENTITY_LINKING, {
|
|
12
61
|
getLinkedProfile: async (details) => {
|
|
13
62
|
const ctx = service.ctx;
|
|
14
63
|
const credsResource = ctx.resource(AUTH_IDENTITY_CREDENTIALS);
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
credential: loginService(details),
|
|
20
|
-
}
|
|
64
|
+
const cred = await credsResource.load({
|
|
65
|
+
type: details.type,
|
|
66
|
+
userId: externalKey(details),
|
|
67
|
+
credential: loginService(details),
|
|
21
68
|
});
|
|
22
|
-
const cred = creds[0] ?? null;
|
|
23
69
|
if (cred == null)
|
|
24
70
|
return null;
|
|
25
71
|
const profileResource = ctx.resource(AUTH_IDENTITY_PROFILE);
|
|
26
|
-
const profile = await profileResource.load(cred.profileId
|
|
72
|
+
const profile = await profileResource.load({ profileId: cred.profileId });
|
|
27
73
|
if (profile == null)
|
|
28
74
|
return null;
|
|
29
75
|
return {
|
|
@@ -31,7 +77,7 @@ export const makeIdentityLinkingService = () => {
|
|
|
31
77
|
role: profile.role,
|
|
32
78
|
userId: profile.userId ?? profile.profileId,
|
|
33
79
|
profileId: profile.profileId,
|
|
34
|
-
|
|
80
|
+
entitySlug: await slugOf(profile.entityId),
|
|
35
81
|
scopes: profile.scopes,
|
|
36
82
|
};
|
|
37
83
|
},
|
|
@@ -40,19 +86,52 @@ export const makeIdentityLinkingService = () => {
|
|
|
40
86
|
const accountResource = ctx.resource(AUTH_IDENTITY_ACCOUNT);
|
|
41
87
|
const profileResource = ctx.resource(AUTH_IDENTITY_PROFILE);
|
|
42
88
|
const credsResource = ctx.resource(AUTH_IDENTITY_CREDENTIALS);
|
|
43
|
-
|
|
89
|
+
const entityResource = ctx.resource(AUTH_IDENTITY_ORG_ENTITY);
|
|
90
|
+
const resolver = ctx.service(ENTITY_RESOLVER);
|
|
91
|
+
// A person the platform already knows is LINKED, not registered again. Everything below
|
|
92
|
+
// this point creates an organization, an account and a profile, and doing that for a second
|
|
93
|
+
// login method is what put one email in two entities.
|
|
94
|
+
const known = meta.force === true ? null : await findPlatformIdentity(meta.username);
|
|
95
|
+
if (known != null) {
|
|
96
|
+
await credsResource.create({
|
|
97
|
+
challenge: '',
|
|
98
|
+
type: details.type,
|
|
99
|
+
userId: externalKey(details),
|
|
100
|
+
profileId: known.profileId,
|
|
101
|
+
credential: loginService(details),
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
type: details.type,
|
|
105
|
+
role: known.role,
|
|
106
|
+
userId: known.userId ?? known.profileId,
|
|
107
|
+
profileId: known.profileId,
|
|
108
|
+
entitySlug: await slugOf(known.entityId),
|
|
109
|
+
scopes: known.scopes,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// Every account gets its own organization. The entity record is created FIRST because it
|
|
113
|
+
// owns the two values that outlive everything else here: the id the account and its profiles
|
|
114
|
+
// are keyed by, and the frozen `iamKey` that realms and object names are minted from.
|
|
115
|
+
const entity = await entityResource.create({
|
|
116
|
+
slug: await resolver.mintSlug(),
|
|
117
|
+
formerSlugs: [],
|
|
118
|
+
// Frozen at birth and never recomputed. It cannot be the slug — the slug moves — and it
|
|
119
|
+
// cannot be the record id, which does not exist until this create returns.
|
|
120
|
+
iamKey: createIdOfLength(16, IdStyle.Base58),
|
|
121
|
+
names: {},
|
|
122
|
+
createdAt: new Date(),
|
|
123
|
+
});
|
|
124
|
+
const entityId = entity.id;
|
|
44
125
|
let accountId = null;
|
|
45
|
-
let entityId = null;
|
|
46
126
|
for (let i = 0; i < MAX_SLUG_RETRIES; i++) {
|
|
47
127
|
const credential = createIdOfLength(16, IdStyle.Base58);
|
|
48
128
|
try {
|
|
49
129
|
const account = await accountResource.create({
|
|
50
130
|
credential,
|
|
51
131
|
name: meta.username,
|
|
52
|
-
entityId
|
|
132
|
+
entityId,
|
|
53
133
|
});
|
|
54
134
|
accountId = account.id;
|
|
55
|
-
entityId = account.credential;
|
|
56
135
|
break;
|
|
57
136
|
}
|
|
58
137
|
catch (err) {
|
|
@@ -61,7 +140,7 @@ export const makeIdentityLinkingService = () => {
|
|
|
61
140
|
throw err;
|
|
62
141
|
}
|
|
63
142
|
}
|
|
64
|
-
if (accountId == null
|
|
143
|
+
if (accountId == null) {
|
|
65
144
|
throw new Error('Failed to generate unique account credential after retries');
|
|
66
145
|
}
|
|
67
146
|
const profileId = [details.type, accountId].join(EXTERNAL_KEY_DELIMITER);
|
|
@@ -80,7 +159,7 @@ export const makeIdentityLinkingService = () => {
|
|
|
80
159
|
}
|
|
81
160
|
catch (err) {
|
|
82
161
|
if (err?.code === 11000 || err?.message?.includes('duplicate')) {
|
|
83
|
-
profile = await profileResource.get(profileId
|
|
162
|
+
profile = await profileResource.get({ profileId });
|
|
84
163
|
}
|
|
85
164
|
else {
|
|
86
165
|
throw err;
|
|
@@ -98,7 +177,7 @@ export const makeIdentityLinkingService = () => {
|
|
|
98
177
|
role: profile.role,
|
|
99
178
|
userId: profile.userId ?? profile.profileId,
|
|
100
179
|
profileId: profile.profileId,
|
|
101
|
-
|
|
180
|
+
entitySlug: await slugOf(profile.entityId),
|
|
102
181
|
scopes: profile.scopes,
|
|
103
182
|
};
|
|
104
183
|
},
|
|
@@ -120,20 +199,32 @@ export const makeIdentityLinkingService = () => {
|
|
|
120
199
|
}
|
|
121
200
|
return result;
|
|
122
201
|
},
|
|
202
|
+
unlinkCredentials: async (details) => {
|
|
203
|
+
const ctx = service.ctx;
|
|
204
|
+
const credsResource = ctx.resource(AUTH_IDENTITY_CREDENTIALS);
|
|
205
|
+
const cred = await credsResource.load({
|
|
206
|
+
type: details.type,
|
|
207
|
+
userId: externalKey(details),
|
|
208
|
+
credential: loginService(details),
|
|
209
|
+
});
|
|
210
|
+
if (cred?.id == null)
|
|
211
|
+
return;
|
|
212
|
+
await credsResource.delete(cred.id);
|
|
213
|
+
},
|
|
123
214
|
getOwnerProfiles: async (entityId) => {
|
|
124
215
|
const ctx = service.ctx;
|
|
125
216
|
const profileResource = ctx.resource(AUTH_IDENTITY_PROFILE);
|
|
126
|
-
const { items: profiles } = await profileResource.list({
|
|
127
|
-
return profiles.map(p => ({
|
|
217
|
+
const { items: profiles } = await profileResource.list({ entityId });
|
|
218
|
+
return await Promise.all(profiles.map(async (p) => ({
|
|
128
219
|
id: p.profileId,
|
|
129
220
|
name: p.name,
|
|
130
221
|
credential: p.credential,
|
|
131
|
-
|
|
222
|
+
entitySlug: await slugOf(p.entityId),
|
|
132
223
|
scopes: p.scopes,
|
|
133
224
|
groups: p.groups,
|
|
134
225
|
permissions: p.permissions,
|
|
135
226
|
attributes: p.attributes,
|
|
136
|
-
}));
|
|
227
|
+
})));
|
|
137
228
|
},
|
|
138
229
|
getOwnerCredentials: async (userId, entityId, type) => {
|
|
139
230
|
const ctx = service.ctx;
|
|
@@ -150,17 +241,16 @@ export const makeIdentityLinkingService = () => {
|
|
|
150
241
|
};
|
|
151
242
|
if (type != null)
|
|
152
243
|
credsFilter.type = type;
|
|
153
|
-
const
|
|
154
|
-
if (
|
|
244
|
+
const cred = await credsResource.load(credsFilter);
|
|
245
|
+
if (cred == null)
|
|
155
246
|
return undefined;
|
|
156
|
-
const cred = creds[0];
|
|
157
247
|
const profile = profiles.find(p => p.profileId === cred.profileId) ?? profiles[0];
|
|
158
248
|
return {
|
|
159
249
|
type: cred.type,
|
|
160
250
|
role: profile.role,
|
|
161
251
|
userId: profile.userId ?? profile.profileId,
|
|
162
252
|
profileId: profile.profileId,
|
|
163
|
-
|
|
253
|
+
entitySlug: await slugOf(profile.entityId),
|
|
164
254
|
scopes: profile.scopes,
|
|
165
255
|
challenge: cred.challenge,
|
|
166
256
|
credential: cred.credential,
|
package/build/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAGpD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/build/types.d.ts
CHANGED
|
@@ -6,22 +6,28 @@ import type { AuthCredentials, AuthPayload, AuthRole, Profile } from '@owlmeans/
|
|
|
6
6
|
import type { ProviderProfileDetails } from '@owlmeans/oidc';
|
|
7
7
|
/**
|
|
8
8
|
* Local account record — one per user.
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
|
+
* `id` is the Mongo resource id; `credential` is the account's stable unique key. `entityId`
|
|
11
|
+
* (inherited from Profile below) holds the organization entity's record id — never its slug.
|
|
10
12
|
*/
|
|
11
|
-
export interface IdentityAccount extends Profile, ResourceRecord {
|
|
13
|
+
export interface IdentityAccount extends Omit<Profile, 'entitySlug'>, ResourceRecord {
|
|
12
14
|
id: string;
|
|
13
15
|
credential: string;
|
|
16
|
+
/** Stable organization-entity id. Renaming the organization does not touch this. */
|
|
17
|
+
entityId?: string;
|
|
14
18
|
}
|
|
15
19
|
/**
|
|
16
20
|
* Local profile record — ties a user to an entity with a role.
|
|
17
21
|
* Mirrors IAMProfile from @owlmeans/auth backend.
|
|
18
22
|
*/
|
|
19
|
-
export interface IdentityProfile extends Profile, ResourceRecord {
|
|
23
|
+
export interface IdentityProfile extends Omit<Profile, 'entitySlug'>, ResourceRecord {
|
|
20
24
|
id: string;
|
|
21
25
|
profileId: string;
|
|
22
26
|
userId?: string;
|
|
23
27
|
role: AuthRole;
|
|
24
28
|
expiresAt?: Date;
|
|
29
|
+
/** Stable organization-entity id — the value every per-organization query filters on. */
|
|
30
|
+
entityId?: string;
|
|
25
31
|
}
|
|
26
32
|
/**
|
|
27
33
|
* Provider credentials record — one per provider link per profile.
|
|
@@ -32,6 +38,27 @@ export interface IdentityProfile extends Profile, ResourceRecord {
|
|
|
32
38
|
export interface IdentityCredentials extends AuthCredentials, ResourceRecord {
|
|
33
39
|
profileId: string;
|
|
34
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* An organization entity — the record every per-organization store keys on.
|
|
43
|
+
*
|
|
44
|
+
* Its `id` is the stable entity id. The slug is the value users, URLs and tokens see, and it may
|
|
45
|
+
* move; nothing here except `slug` itself changes when it does, which is the entire point of the
|
|
46
|
+
* record existing.
|
|
47
|
+
*/
|
|
48
|
+
export interface OrgEntity extends ResourceRecord {
|
|
49
|
+
id?: string;
|
|
50
|
+
slug: string;
|
|
51
|
+
formerSlugs?: string[];
|
|
52
|
+
iamKey: string;
|
|
53
|
+
/**
|
|
54
|
+
* Names this organization is known by in systems that cannot rename: a Kubernetes namespace, a
|
|
55
|
+
* storage prefix, an IAM realm. Minted once through `mintName` and read back forever after.
|
|
56
|
+
*/
|
|
57
|
+
names?: Record<string, string>;
|
|
58
|
+
createdAt: Date;
|
|
59
|
+
updatedAt?: Date;
|
|
60
|
+
}
|
|
61
|
+
export type OrgEntityResource = MongoResource<OrgEntity>;
|
|
35
62
|
export type IdentityAccountResource = MongoResource<IdentityAccount>;
|
|
36
63
|
export type IdentityProfileResource = MongoResource<IdentityProfile>;
|
|
37
64
|
export type IdentityCredentialsResource = MongoResource<IdentityCredentials>;
|
|
@@ -43,6 +70,17 @@ export interface IdentityLinkingService extends InitializedService {
|
|
|
43
70
|
getLinkedProfile: (details: ProviderProfileDetails) => Promise<AuthPayload | null>;
|
|
44
71
|
linkProfile: (details: ProviderProfileDetails, meta: AccountMeta) => Promise<AuthPayload>;
|
|
45
72
|
linkCredentials: (details: ProviderProfileDetails) => Promise<AuthPayload>;
|
|
73
|
+
/**
|
|
74
|
+
* Forget which profile an external login maps to, so the next `linkProfile` establishes it anew.
|
|
75
|
+
*
|
|
76
|
+
* The stored mapping is keyed `{type, userId, credential}` under a unique index, so a caller
|
|
77
|
+
* that has decided the existing mapping is wrong cannot simply write over it — it has to be
|
|
78
|
+
* retired first. That decision belongs to whoever owns the login path (a decorator serving a
|
|
79
|
+
* different population than the platform's own customers, say); the key format belongs here.
|
|
80
|
+
*
|
|
81
|
+
* Idempotent: a login that maps to nothing is already in the state this promises.
|
|
82
|
+
*/
|
|
83
|
+
unlinkCredentials: (details: ProviderProfileDetails) => Promise<void>;
|
|
46
84
|
getOwnerProfiles: (entityId: string) => Promise<Profile[]>;
|
|
47
85
|
getOwnerCredentials: (userId: string, entityId?: string, type?: string) => Promise<AuthCredentials | undefined>;
|
|
48
86
|
}
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AACrF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAE5D
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/server-auth-identity",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.21",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -22,20 +22,21 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
26
|
-
"@owlmeans/
|
|
27
|
-
"@owlmeans/
|
|
28
|
-
"@owlmeans/
|
|
29
|
-
"@owlmeans/
|
|
30
|
-
"@owlmeans/
|
|
31
|
-
"@owlmeans/
|
|
25
|
+
"@owlmeans/auth": "^0.1.18-rc.17",
|
|
26
|
+
"@owlmeans/auth-common": "^0.1.18-rc.21",
|
|
27
|
+
"@owlmeans/basic-ids": "^0.1.18-rc.17",
|
|
28
|
+
"@owlmeans/context": "^0.1.18-rc.16",
|
|
29
|
+
"@owlmeans/mongo-resource": "^0.1.18-rc.20",
|
|
30
|
+
"@owlmeans/oidc": "^0.1.18-rc.29",
|
|
31
|
+
"@owlmeans/resource": "^0.1.18-rc.17",
|
|
32
|
+
"@owlmeans/server-context": "^0.1.18-rc.20"
|
|
32
33
|
},
|
|
33
34
|
"peerDependencies": {
|
|
34
35
|
"mongodb": "*"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@owlmeans/dep-config": "workspace:*",
|
|
38
|
-
"@types/bun": "^1.
|
|
39
|
+
"@types/bun": "^1.4.0",
|
|
39
40
|
"nodemon": "^3.1.14",
|
|
40
41
|
"typescript": "^7.0.2"
|
|
41
42
|
},
|
package/src/consts.ts
CHANGED
|
@@ -7,6 +7,7 @@ export const AUTH_IDENTITY_ACCOUNT = 'auth-identity:account'
|
|
|
7
7
|
export const AUTH_IDENTITY_PROFILE = 'auth-identity:profile'
|
|
8
8
|
export const AUTH_IDENTITY_CREDENTIALS = 'auth-identity:credentials'
|
|
9
9
|
export const AUTH_IDENTITY_LINKING = 'auth-identity:linking'
|
|
10
|
+
export const AUTH_IDENTITY_ORG_ENTITY = 'auth-identity:org-entity'
|
|
10
11
|
|
|
11
12
|
// Colon-free Mongo collection base names. The final collection name is
|
|
12
13
|
// `${resourcePrefix}${collection}` — e.g. with the project prefix 'viam-' this yields
|
|
@@ -15,11 +16,16 @@ export const AUTH_IDENTITY_LINKING = 'auth-identity:linking'
|
|
|
15
16
|
export const AUTH_IDENTITY_ACCOUNT_COLLECTION = 'account'
|
|
16
17
|
export const AUTH_IDENTITY_PROFILE_COLLECTION = 'profile'
|
|
17
18
|
export const AUTH_IDENTITY_CREDENTIALS_COLLECTION = 'credentials'
|
|
19
|
+
export const AUTH_IDENTITY_ORG_ENTITY_COLLECTION = 'org-entity'
|
|
18
20
|
|
|
19
21
|
// Suggested db-config alias for a dedicated config whose resourcePrefix scopes the
|
|
20
22
|
// collection prefix to identity collections only (not the whole database).
|
|
21
23
|
export const AUTH_IDENTITY_DB_ALIAS = 'auth-identity'
|
|
22
24
|
|
|
25
|
+
// How many slugs to try before giving up on minting a free one. Collisions are settled against a
|
|
26
|
+
// unique index, so this bounds a retry loop rather than a probability.
|
|
27
|
+
export const MAX_ENTITY_SLUG_ATTEMPTS = 8
|
|
28
|
+
|
|
23
29
|
// Helper prefixes for stable key derivation
|
|
24
30
|
export const LOGIN_SERVICE_PREFIX = 'service'
|
|
25
31
|
export const EXTERNAL_KEY_DELIMITER = ':'
|
package/src/helper.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BasicContext } from '@owlmeans/context'
|
|
2
|
-
import { makeIdentityAccountResource, makeIdentityProfileResource, makeIdentityCredentialsResource } from './resource.js'
|
|
2
|
+
import { makeIdentityAccountResource, makeIdentityProfileResource, makeIdentityCredentialsResource, makeOrgEntityResource } from './resource.js'
|
|
3
3
|
import { makeIdentityLinkingService } from './service.js'
|
|
4
|
+
import { makeEntityResolverService } from './resolver.js'
|
|
4
5
|
|
|
5
6
|
export const appendAuthIdentityResources = (
|
|
6
7
|
context: BasicContext<any>,
|
|
@@ -9,5 +10,10 @@ export const appendAuthIdentityResources = (
|
|
|
9
10
|
context.registerResource(makeIdentityAccountResource(dbAlias))
|
|
10
11
|
context.registerResource(makeIdentityProfileResource(dbAlias))
|
|
11
12
|
context.registerResource(makeIdentityCredentialsResource(dbAlias))
|
|
13
|
+
context.registerResource(makeOrgEntityResource(dbAlias))
|
|
12
14
|
context.registerService(makeIdentityLinkingService())
|
|
15
|
+
// Registering the resolver is what tells the server boundary that this deployment HAS
|
|
16
|
+
// organizations: without it `request.entity` stays undefined and every consumer falls back to
|
|
17
|
+
// treating the token's slug as the only entity value there is.
|
|
18
|
+
context.registerService(makeEntityResolverService())
|
|
13
19
|
}
|