Release v2.20.1: migrate authentication to Better Auth
This commit is contained in:
1 parent
e9a53f577c
commit
fba4f99ff7
92 files changed
+5085
-1943
No files matched your search
@@ -2,7 +2,10 @@ const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
|
||||
require('../src/common');
|
||||
|
||||
const { buildUsersEditViewModel, buildUsersAddViewModel } = require('../src/web/routes/settings/users/form-view-model');
|
||||
const rbacData = require('../src/web/lib/auth/rbac-data');
|
||||
const usersFormTemplate = fs.readFileSync(require.resolve('../src/web/views/settings/users/form.hbs'), 'utf8');
|
||||
|
||||
test('user edit view model includes delete confirmation text', () => {
|
||||
@@ -35,4 +38,78 @@ test('user form keeps username editable in the admin section', () => {
|
||||
assert.ok(!usersFormTemplate.includes('{{#if isEdit}}disabled{{else}}required{{/if}}'));
|
||||
assert.ok(usersFormTemplate.includes('required />'));
|
||||
assert.match(usersFormTemplate, /class="btn-group ms-auto" role="group" aria-label=/);
|
||||
});
|
||||
|
||||
test('user edit view model carries Better Auth sign-in methods without provider account ids', async () => {
|
||||
const pool = {
|
||||
async query(sql) {
|
||||
if (String(sql).includes('FROM a_users u')) {
|
||||
return [[{ id: 12, name: 'User', username: 'user', email: 'user@example.test', email_verified: 1, two_factor_enabled: 0, role_ids_csv: '' }]];
|
||||
}
|
||||
if (String(sql).includes('FROM a_accounts')) {
|
||||
return [[{ provider_id: 'credential', account_id: '12' }, { provider_id: 'google', account_id: 'google-subject' }]];
|
||||
}
|
||||
if (String(sql).includes('FROM a_user_passkeys')) return [[{ id: 'passkey-1', name: 'Work laptop', created_at: new Date() }]];
|
||||
return [[]];
|
||||
}
|
||||
};
|
||||
|
||||
const user = await rbacData.fetchUserWithRoles(pool, 12);
|
||||
const model = buildUsersEditViewModel(user, '', { id: 1 }, []);
|
||||
|
||||
assert.deepEqual(model.authMethods, [
|
||||
{ providerId: 'credential', label: 'Password', isCredential: true },
|
||||
{ providerId: 'google', label: 'Google', isCredential: false }
|
||||
]);
|
||||
assert.equal(model.user.twoFactorEnabled, false);
|
||||
assert.deepEqual(model.passkeys, [{ id: 'passkey-1', name: 'Work laptop', created_at: model.passkeys[0].created_at }]);
|
||||
assert.equal(model.user.canUnlinkPasskeys, true);
|
||||
assert.doesNotMatch(JSON.stringify(model.authMethods), /google-subject/);
|
||||
assert.ok(usersFormTemplate.includes('Sign-in methods'));
|
||||
assert.ok(usersFormTemplate.includes('{{#if isEdit}}'));
|
||||
assert.doesNotMatch(usersFormTemplate, /Linked SSO or OAuth accounts will appear here when configured\./);
|
||||
assert.ok(usersFormTemplate.includes('user.passkeys'));
|
||||
assert.ok(usersFormTemplate.includes('data-admin-passkey-group'));
|
||||
assert.ok(usersFormTemplate.includes('data-admin-passkey-list'));
|
||||
assert.ok(usersFormTemplate.includes('bi-arrow-return-right'));
|
||||
assert.ok(usersFormTemplate.includes('/passkeys/{{id}}/unlink'));
|
||||
assert.ok(usersFormTemplate.includes('list-group-item d-flex align-items-start gap-3 px-0'));
|
||||
});
|
||||
|
||||
test('password-only users still see the available two-factor option', () => {
|
||||
const model = buildUsersEditViewModel({
|
||||
id: 12,
|
||||
inUse: false,
|
||||
roleIds: [],
|
||||
twoFactorEnabled: false,
|
||||
authMethods: [{ providerId: 'credential', label: 'Password' }]
|
||||
}, '', { id: 1 }, []);
|
||||
|
||||
assert.equal(model.user.twoFactorEnabled, false);
|
||||
assert.ok(usersFormTemplate.includes('Two-step verification'));
|
||||
assert.ok(usersFormTemplate.includes('Not enabled'));
|
||||
});
|
||||
|
||||
test('admin edit shows two-factor status as an additional sign-in method', async () => {
|
||||
const pool = {
|
||||
async query(sql) {
|
||||
if (String(sql).includes('FROM a_users u')) {
|
||||
return [[{ id: 13, name: 'User', username: 'user', email: 'user@example.test', email_verified: 1, two_factor_enabled: 1, role_ids_csv: '' }]];
|
||||
}
|
||||
if (String(sql).includes('FROM a_accounts')) return [[{ provider_id: 'credential', account_id: '13' }]];
|
||||
return [[]];
|
||||
}
|
||||
};
|
||||
|
||||
const user = await rbacData.fetchUserWithRoles(pool, 13);
|
||||
const model = buildUsersEditViewModel(user, '', { id: 1 }, []);
|
||||
assert.equal(model.user.twoFactorEnabled, true);
|
||||
assert.ok(usersFormTemplate.includes('Enabled'));
|
||||
});
|
||||
|
||||
test('user edit view model withholds passkey unlink from the account owner', () => {
|
||||
const user = { id: 12, passkeys: [{ id: 'passkey-1', name: 'Work laptop' }] };
|
||||
const model = buildUsersEditViewModel(user, '', { id: 12 }, []);
|
||||
assert.equal(model.user.canUnlinkPasskeys, false);
|
||||
assert.equal(model.passkeys.length, 1);
|
||||
});
|
||||
Reference in new issue
Block a user