@jskit-ai/auth-provider-local-core 0.1.36 → 0.1.38
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/package.descriptor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
"packageVersion": 1,
|
|
3
3
|
"packageId": "@jskit-ai/auth-provider-local-core",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.38",
|
|
5
5
|
"kind": "runtime",
|
|
6
6
|
"description": "Local auth provider with a file backend default and no database requirement.",
|
|
7
7
|
"dependsOn": [
|
|
@@ -64,8 +64,8 @@ export default Object.freeze({
|
|
|
64
64
|
"mutations": {
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"runtime": {
|
|
67
|
-
"@jskit-ai/auth-core": "0.1.
|
|
68
|
-
"@jskit-ai/kernel": "0.1.
|
|
67
|
+
"@jskit-ai/auth-core": "0.1.134",
|
|
68
|
+
"@jskit-ai/kernel": "0.1.136",
|
|
69
69
|
"nodemailer": "^9.0.3",
|
|
70
70
|
"dotenv": "^16.4.5"
|
|
71
71
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/auth-provider-local-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.38",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"./server/lib/index": "./src/server/lib/index.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@jskit-ai/auth-core": "0.1.
|
|
15
|
-
"@jskit-ai/kernel": "0.1.
|
|
14
|
+
"@jskit-ai/auth-core": "0.1.134",
|
|
15
|
+
"@jskit-ai/kernel": "0.1.136",
|
|
16
16
|
"nodemailer": "^9.0.3"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -154,23 +154,6 @@ async function findExistingAppProfile(user, profileProjector) {
|
|
|
154
154
|
return profile ? requireProfileResult(profile, "findByIdentity") : null;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
async function findExistingAppProfileByLogin(login, profileProjector) {
|
|
158
|
-
if (!profileProjector || typeof profileProjector.findByLogin !== "function") {
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
const profile = await profileProjector.findByLogin(login);
|
|
162
|
-
return profile ? requireProfileResult(profile, "findByLogin") : null;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function appProfileLocalUserId(profile = null) {
|
|
166
|
-
if (
|
|
167
|
-
String(profile?.authProvider || "").trim().toLowerCase() !== PROVIDER_ID
|
|
168
|
-
) {
|
|
169
|
-
return "";
|
|
170
|
-
}
|
|
171
|
-
return String(profile?.authProviderUserSid || "").trim();
|
|
172
|
-
}
|
|
173
|
-
|
|
174
157
|
async function buildSessionAuthPayload({ devAuth, profileProjector, request, session, user }) {
|
|
175
158
|
if (!isDevAuthSession(session)) {
|
|
176
159
|
return buildAuthPayload({ user, session: null, profileProjector });
|
|
@@ -247,18 +230,17 @@ function validateEmailInput(email) {
|
|
|
247
230
|
|
|
248
231
|
function devLoginAsValidationError(fieldErrors = {}) {
|
|
249
232
|
const messages = Object.values(fieldErrors).filter(Boolean);
|
|
250
|
-
return new AppError(400, messages[0] || "Provide a user id
|
|
233
|
+
return new AppError(400, messages[0] || "Provide a user id or email.", {
|
|
251
234
|
details: {
|
|
252
235
|
fieldErrors
|
|
253
236
|
}
|
|
254
237
|
});
|
|
255
238
|
}
|
|
256
239
|
|
|
257
|
-
function devLoginAsUserNotFound({ email = "",
|
|
240
|
+
function devLoginAsUserNotFound({ email = "", userId = "" } = {}) {
|
|
258
241
|
return devLoginAsValidationError({
|
|
259
242
|
...(userId ? { userId: "User not found." } : {}),
|
|
260
|
-
...(email ? { email: "User not found." } : {})
|
|
261
|
-
...(login ? { login: "User not found." } : {})
|
|
243
|
+
...(email ? { email: "User not found." } : {})
|
|
262
244
|
});
|
|
263
245
|
}
|
|
264
246
|
|
|
@@ -476,12 +458,10 @@ function createLocalAuthService({
|
|
|
476
458
|
ensureDevAuthExchangeAvailable(devAuth, request);
|
|
477
459
|
const userId = String(input?.userId || "").trim();
|
|
478
460
|
const email = normalizeEmail(input?.email || "");
|
|
479
|
-
|
|
480
|
-
if (!userId && !email && !login) {
|
|
461
|
+
if (!userId && !email) {
|
|
481
462
|
throw devLoginAsValidationError({
|
|
482
|
-
userId: "Provide a user id
|
|
483
|
-
email: "Provide a user id
|
|
484
|
-
login: "Provide a user id, email, or login name."
|
|
463
|
+
userId: "Provide a user id or email.",
|
|
464
|
+
email: "Provide a user id or email."
|
|
485
465
|
});
|
|
486
466
|
}
|
|
487
467
|
|
|
@@ -490,18 +470,12 @@ function createLocalAuthService({
|
|
|
490
470
|
if (!user && email) {
|
|
491
471
|
user = await tx.users.findByEmail(email);
|
|
492
472
|
}
|
|
493
|
-
let appProfile = null;
|
|
494
|
-
if (!user && login) {
|
|
495
|
-
appProfile = await findExistingAppProfileByLogin(login, profileProjector);
|
|
496
|
-
const localUserId = appProfileLocalUserId(appProfile);
|
|
497
|
-
user = localUserId ? await tx.users.findById(localUserId) : null;
|
|
498
|
-
}
|
|
499
473
|
if (!user || user.disabled) {
|
|
500
|
-
throw devLoginAsUserNotFound({ email,
|
|
474
|
+
throw devLoginAsUserNotFound({ email, userId });
|
|
501
475
|
}
|
|
502
|
-
appProfile
|
|
476
|
+
const appProfile = await findExistingAppProfile(user, profileProjector);
|
|
503
477
|
if (profileProjector && !appProfile) {
|
|
504
|
-
throw devLoginAsUserNotFound({ email,
|
|
478
|
+
throw devLoginAsUserNotFound({ email, userId });
|
|
505
479
|
}
|
|
506
480
|
const session = await createSessionForUser(tx, user, {
|
|
507
481
|
purpose: DEV_AUTH_SESSION_PURPOSE
|
|
@@ -158,9 +158,6 @@ function createLazyProfileProjector(scope) {
|
|
|
158
158
|
findByIdentity(identity, options = {}) {
|
|
159
159
|
return resolveMethod("findByIdentity")(identity, options);
|
|
160
160
|
},
|
|
161
|
-
findByLogin(login, options = {}) {
|
|
162
|
-
return resolveMethod("findByLogin")(login, options);
|
|
163
|
-
},
|
|
164
161
|
syncIdentityProfile(profile, options = {}) {
|
|
165
162
|
return resolveMethod("syncIdentityProfile")(profile, options);
|
|
166
163
|
}
|
|
@@ -234,109 +234,6 @@ test("local file auth login-as issues native cookies for an existing user", asyn
|
|
|
234
234
|
assert.equal(authenticated.sessionPurpose, "dev-auth");
|
|
235
235
|
});
|
|
236
236
|
|
|
237
|
-
test("local login-as resolves an application login through its existing auth profile link", async () => {
|
|
238
|
-
const projectedProfile = {
|
|
239
|
-
id: "app-user-ada",
|
|
240
|
-
authProvider: "local",
|
|
241
|
-
authProviderUserSid: "",
|
|
242
|
-
displayName: "Ada",
|
|
243
|
-
email: "ada@example.com",
|
|
244
|
-
username: "merc"
|
|
245
|
-
};
|
|
246
|
-
let syncCalls = 0;
|
|
247
|
-
const { app } = await createStartedApp({
|
|
248
|
-
env: devAuthEnv(),
|
|
249
|
-
profileProjector: {
|
|
250
|
-
async findByIdentity() {
|
|
251
|
-
return projectedProfile;
|
|
252
|
-
},
|
|
253
|
-
async findByLogin(login) {
|
|
254
|
-
return login === "merc" ? projectedProfile : null;
|
|
255
|
-
},
|
|
256
|
-
async syncIdentityProfile(profile) {
|
|
257
|
-
syncCalls += 1;
|
|
258
|
-
return {
|
|
259
|
-
...projectedProfile,
|
|
260
|
-
authProviderUserSid: profile.authProviderUserSid
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
const authService = app.make("authService");
|
|
266
|
-
const registered = await authService.register({
|
|
267
|
-
displayName: "Ada",
|
|
268
|
-
email: "ada@example.com",
|
|
269
|
-
password: "correct horse battery staple"
|
|
270
|
-
});
|
|
271
|
-
projectedProfile.authProviderUserSid = registered.actor.providerUserId;
|
|
272
|
-
syncCalls = 0;
|
|
273
|
-
|
|
274
|
-
const impersonated = await authService.devLoginAs(createDevAuthExchangeRequest(), {
|
|
275
|
-
login: "merc"
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
assert.equal(impersonated.profile.id, "app-user-ada");
|
|
279
|
-
assert.equal(impersonated.actor.providerUserId, registered.actor.providerUserId);
|
|
280
|
-
assert.equal(impersonated.session.purpose, "dev-auth");
|
|
281
|
-
assert.equal(syncCalls, 0);
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
test("local login-as rejects unknown, disabled, and non-local application logins", async () => {
|
|
285
|
-
const disabledProfile = {
|
|
286
|
-
id: "app-user-disabled",
|
|
287
|
-
authProvider: "local",
|
|
288
|
-
authProviderUserSid: "local-user-disabled",
|
|
289
|
-
displayName: "Disabled",
|
|
290
|
-
email: "disabled-login@example.com",
|
|
291
|
-
username: "disabled"
|
|
292
|
-
};
|
|
293
|
-
const { app } = await createStartedApp({
|
|
294
|
-
env: devAuthEnv(),
|
|
295
|
-
profileProjector: {
|
|
296
|
-
async findByIdentity() {
|
|
297
|
-
return null;
|
|
298
|
-
},
|
|
299
|
-
async findByLogin(login) {
|
|
300
|
-
if (login === "disabled") {
|
|
301
|
-
return disabledProfile;
|
|
302
|
-
}
|
|
303
|
-
if (login === "external") {
|
|
304
|
-
return {
|
|
305
|
-
id: "app-user-external",
|
|
306
|
-
authProvider: "external",
|
|
307
|
-
authProviderUserSid: "external-user-1",
|
|
308
|
-
displayName: "External",
|
|
309
|
-
email: "external@example.com",
|
|
310
|
-
username: login
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
return null;
|
|
314
|
-
},
|
|
315
|
-
async syncIdentityProfile() {
|
|
316
|
-
throw new Error("preview login must not synchronize profiles");
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
const backend = app.make("auth.local.backend");
|
|
321
|
-
await backend.withTransaction(async (tx) => {
|
|
322
|
-
await tx.users.create({
|
|
323
|
-
disabled: true,
|
|
324
|
-
displayName: "Disabled",
|
|
325
|
-
email: disabledProfile.email,
|
|
326
|
-
id: disabledProfile.authProviderUserSid,
|
|
327
|
-
password: await hashPassword("stored password value")
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
const authService = app.make("authService");
|
|
331
|
-
|
|
332
|
-
for (const login of ["missing", "disabled", "external"]) {
|
|
333
|
-
await assert.rejects(
|
|
334
|
-
() => authService.devLoginAs(createDevAuthExchangeRequest(), { login }),
|
|
335
|
-
/User not found/
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
|
-
|
|
340
237
|
test("local login-as never invokes the mutating profile projector", async () => {
|
|
341
238
|
const projectedProfile = {
|
|
342
239
|
id: "app-user-ada",
|