Skip to content

Commit

Permalink
Merge pull request #477 from curveball/flight-tweaks
Browse files Browse the repository at this point in the history
Various tweaks and bugfixes from a transatlantic
  • Loading branch information
evert authored Nov 9, 2023
2 parents d34b06b + f89b03b commit ff42391
Show file tree
Hide file tree
Showing 11 changed files with 407 additions and 361 deletions.
6 changes: 1 addition & 5 deletions .env.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ REGISTRATION_ENABLED=1
#
# Using Redis is a must if you paln on running multiple load-balanced
# instances of a12n-server
# REDIS_HOST=
# REDIS_PORT=6379
#
# Redis password is optional
# REDIS_PASSWORD=
# REDIS_URI=redis://localhost


# OAuth2 settings
Expand Down
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Changelog
* The Docker distribution now runs on Node 20 (upgraded from 16).
* Fixed a 500 error in the OAuth2 password flow.
* Updated to simplewebauthn 8.
* Upgrade to Redis 4.
* Improve user audit logging for various OAuth2 flows.
* Use SQLite3 WAL mode for better concurrency.


0.24.0-alpha.0 (2023-10-04)
Expand Down
663 changes: 332 additions & 331 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
"@types/node": "^16.11.26",
"@types/nodemailer": "^6.4.1",
"@types/qrcode": "^1.4.0",
"@types/redis": "^2.8.32",
"@types/sinon": "^10.0.0",
"@types/sinon-chai": "^3.2.8",
"@typescript-eslint/eslint-plugin": "^6.7.4",
Expand Down Expand Up @@ -89,7 +88,7 @@
"@curveball/problem": "^0.5.0",
"@curveball/router": "^0.6.0",
"@curveball/session": "^0.10.0",
"@curveball/session-redis": "^0.5.0",
"@curveball/session-redis": "^0.6.0",
"@curveball/validator": "^0.10.0",
"@simplewebauthn/browser": "^8.3.1",
"@simplewebauthn/server": "^8.2.0",
Expand All @@ -100,8 +99,8 @@
"geoip-lite": "^1.0.10",
"handlebars": "^4.7.7",
"jose": "^4.6.1",
"knex": "^2.0.0",
"mysql2": "^3.6.1",
"knex": "^3.0.1",
"mysql2": "^2.2.5",
"nodemailer": "^6.5.0",
"otplib": "^12.0.1",
"pg": "^8.7.1",
Expand Down
6 changes: 5 additions & 1 deletion src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ export function getSettings(): Knex.Config {
let client;
let searchPath;
let useNullAsDefault: undefined|true = undefined;
const pool: Knex.PoolConfig = {
min: 0,
max: 10
};

if (process.env.PG_DATABASE) {

Expand Down Expand Up @@ -181,7 +185,7 @@ export function getSettings(): Knex.Config {
directory: path.join(__dirname, 'migrations'),
loadExtensions: ['.js'],
},
pool: { min: 0, max: 10 },
pool,
debug: process.env.DEBUG ? true : false,
useNullAsDefault: useNullAsDefault,
};
Expand Down
7 changes: 7 additions & 0 deletions src/log/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ export default async function log(
) {

if (isContext(arg1)) {

if (process.env.NODE_ENV === 'dev') {
if (!arg1.session.user?.id) {
throw new Error('[DEBUG] user_log is invoked with a context that didn\'t have a user. This log entry will be ignored');
}
}

await addLogEntry(
eventType,
arg1.ip() ?? '',
Expand Down
19 changes: 10 additions & 9 deletions src/log/types.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
export enum EventType {
loginSuccess = 1,
loginFailed,
totpFailed,
changePasswordSuccess,
resetPasswordRequest,
resetPasswordSuccess,
loginFailedInactive,
webAuthnFailed,
tokenRevoked,
loginFailed = 2,
totpFailed = 3,
changePasswordSuccess = 4,
resetPasswordRequest = 5,
resetPasswordSuccess = 6,
loginFailedInactive = 7,
webAuthnFailed = 8,
tokenRevoked = 9,

oauth2BadRedirect = 11,
generateAccessToken,
generateAccessToken = 12,
}

export type LogEntry = {
Expand Down
4 changes: 1 addition & 3 deletions src/main-mw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ export default function (): Middleware {
store: process.env.REDIS_HOST ? new RedisStore({
prefix: 'A12N-session',
clientOptions: {
port: process.env.REDIS_PORT ? parseInt(process.env.REDIS_PORT, 10) : 6379,
host: process.env.REDIS_HOST ? process.env.REDIS_HOST : '127.0.0.1',
password: process.env.REDIS_PASSWORD ? process.env.REDIS_PASSWORD : undefined,
url: process.env.REDIS_URI!,
},
}) : 'memory',
cookieName: 'A12N',
Expand Down
18 changes: 18 additions & 0 deletions src/migrations/20231108041315_sqlite_wal_mode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Knex } from 'knex';

export async function up(knex: Knex): Promise<void> {

if (knex().client.driverName === 'sqlite3') {
// Changing the mode of the sqlite3 database to WAL
// is basically required to get concurrency.
await knex.raw('PRAGMA journal_mode=WAL');
}

}


export async function down(knex: Knex): Promise<void> {

throw new Error('This migration cannot be reverted yet');

}
2 changes: 1 addition & 1 deletion src/oauth2/controller/authorize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class AuthorizeController extends Controller {
try {
await oauth2Service.requireRedirectUri(oauth2Client, params.redirectUri);
} catch (err) {
log(EventType.oauth2BadRedirect, ctx);
await log(EventType.oauth2BadRedirect, ctx);
throw err;
}

Expand Down
33 changes: 26 additions & 7 deletions src/oauth2/controller/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,21 @@ class TokenController extends Controller {
if (!ctx.request.body.redirect_uri) {
throw new InvalidRequest('The "redirect_uri" property is required');
}
if (!await oauth2Service.validateRedirectUri(oauth2Client, ctx.request.body.redirect_uri)) {
log(EventType.oauth2BadRedirect, ctx);
throw new InvalidRequest('This value for "redirect_uri" is not recognized.');
}
const token = await oauth2Service.generateTokenAuthorizationCode({
client: oauth2Client,
code: ctx.request.body.code,
codeVerifier: ctx.request.body.code_verifier,
secretUsed,
});
if (!await oauth2Service.validateRedirectUri(oauth2Client, ctx.request.body.redirect_uri)) {
await log(
EventType.oauth2BadRedirect,
ctx.ip(),
token.principal.id
);
throw new InvalidRequest('This value for "redirect_uri" is not recognized.');
}


ctx.response.type = 'application/json';
ctx.response.body = {
Expand All @@ -118,16 +123,30 @@ class TokenController extends Controller {
}

if (!await userService.validatePassword(user, ctx.request.body.password)) {
log(EventType.loginFailed, ctx.ip(), user.id);
await log(
EventType.loginFailed,
ctx.ip(),
user.id
);
throw new InvalidGrant('Unknown username or password');
}

if (!user.active) {
log(EventType.loginFailedInactive, ctx.ip(), user.id, ctx.request.headers.get('User-Agent')!);
await log(
EventType.loginFailedInactive,
ctx.ip(),
user.id,
ctx.request.headers.get('User-Agent')!
);
throw new InvalidGrant('User Inactive');
}

log(EventType.loginSuccess, ctx);
await log(
EventType.loginSuccess,
ctx.ip(),
user.id,
ctx.request.headers.get('User-Agent')!
);

const scope: string[] = ctx.request.body.scope?.split(' ') ?? [];

Expand Down

0 comments on commit ff42391

Please sign in to comment.