Release v2.20.4
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile, web, pulse-signage-web) (push) Successful in 1m22s
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile.player, player, pulse-signage-player) (push) Successful in 33s

This commit is contained in:
lzstealth committed 2026-10-25 20:47:38 +00:00
1 parent 7228406929
commit e6c48c6340
10 files changed
+95 -7

No files matched your search

+43 -1
View File
@@ -1,7 +1,49 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const { hashPassword, encodePasswordRecord, verifyEncodedPassword, hashScryptPassword, verifyCredentialPassword } = require('../src/auth');
const { createPasswordCallbacks, createAccountLockSessionHook, createLoginRateLimitResetHook, createPasskeyAuthenticationGuard, resolvePasskeyRpID, getRoleTwoFactorAuthError, ensureBetterAuthClientIp } = require('../src/web/lib/auth/better-auth');
const { createPasswordCallbacks, createAccountLockSessionHook, createLoginRateLimitResetHook, createLoginAuditHook, createPasskeyAuthenticationGuard, resolvePasskeyRpID, getRoleTwoFactorAuthError, ensureBetterAuthClientIp, getTrustedProxies } = require('../src/web/lib/auth/better-auth');
test('completed password, two-factor, and passkey logins record an audit event with request metadata', async () => {
const events = [];
const pool = {};
const hook = createLoginAuditHook(pool, async function (actualPool, req, event) {
assert.equal(actualPool, pool);
events.push({ req, event });
});
for (const path of ['/sign-in/username', '/sign-in/email', '/two-factor/verify-totp', '/two-factor/verify-backup-code', '/passkey/verify-authentication']) {
await hook({
path,
headers: new Headers({ 'x-forwarded-for': '192.0.2.1', 'user-agent': 'test-browser' }),
context: { newSession: { session: { ipAddress: '192.0.2.1' }, user: { id: 7, username: 'alice' } } }
});
}
assert.equal(events.length, 5);
for (const { req, event } of events) {
assert.deepEqual(event, { category: 'authentication', eventType: 'login.success', actorUserId: 7, targetType: 'user', targetId: 7, targetLabel: 'alice' });
assert.equal(req.headers['user-agent'], 'test-browser');
assert.equal(req.headers['x-forwarded-for'], '192.0.2.1');
assert.equal(req.ip, '192.0.2.1');
}
});
test('failed login, pending two-factor, and unrelated session creation do not log a successful login', async () => {
const hook = createLoginAuditHook({}, async function () { assert.fail('Login must not be audited as successful'); });
for (const path of ['/sign-in/username', '/two-factor/verify-totp', '/passkey/verify-authentication']) {
await hook({ path, context: { newSession: null } });
}
await hook({ path: '/two-factor/enable', context: { newSession: { session: {}, user: { id: 7 } } } });
});
test('Better Auth trusted proxies accept comma-separated IPs and CIDRs without trusting proxies by default', async () => {
const { getIPFromHeader } = await import('@better-auth/core/utils/ip');
assert.deepEqual(getTrustedProxies(''), []);
assert.deepEqual(getTrustedProxies(' , '), []);
const trustedProxies = getTrustedProxies(' 192.0.2.2, 198.51.100.0/24, , ::1 ');
assert.deepEqual(trustedProxies, ['192.0.2.2', '198.51.100.0/24', '::1']);
const chain = '203.0.113.1, 192.0.2.2, 198.51.100.2';
assert.equal(getIPFromHeader(chain, { trustedProxies: getTrustedProxies('') }), null);
assert.equal(getIPFromHeader(chain, { trustedProxies }), '203.0.113.1');
});
test('Better Auth client IP falls back to the socket address for direct requests', () => {
for (const address of ['192.0.2.1', '::1', '::ffff:192.0.2.1']) {