Skip to content

Commit

Permalink
Refactoring load-config.js
Browse files Browse the repository at this point in the history
  • Loading branch information
lelemm committed Mar 1, 2025
1 parent 61364fb commit 8d1b5c7
Show file tree
Hide file tree
Showing 15 changed files with 387 additions and 300 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ async function ensureExists(path) {
}

export const up = async function () {
await ensureExists(config.serverFiles);
await ensureExists(config.userFiles);
await ensureExists(config.get('serverFiles'));
await ensureExists(config.get('userFiles'));
};

export const down = async function () {
await fs.rm(config.serverFiles, { recursive: true, force: true });
await fs.rm(config.userFiles, { recursive: true, force: true });
await fs.rm(config.get('serverFiles'), { recursive: true, force: true });
await fs.rm(config.get('userFiles'), { recursive: true, force: true });
};
2 changes: 2 additions & 0 deletions packages/sync-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@babel/preset-typescript": "^7.20.2",
"@types/bcrypt": "^5.0.2",
"@types/better-sqlite3": "^7.6.12",
"@types/convict": "^6",
"@types/cors": "^2.8.13",
"@types/express": "^5.0.0",
"@types/express-actuator": "^1.8.3",
Expand All @@ -56,6 +57,7 @@
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.51.0",
"@typescript-eslint/parser": "^5.51.0",
"convict": "^6.2.4",
"eslint": "^8.33.0",
"eslint-plugin-prettier": "^4.2.1",
"http-proxy-middleware": "^3.0.3",
Expand Down
12 changes: 7 additions & 5 deletions packages/sync-server/src/account-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let _accountDb;

export function getAccountDb() {
if (_accountDb === undefined) {
const dbPath = join(config.serverFiles, 'account.sqlite');
const dbPath = join(config.get('serverFiles'), 'account.sqlite');
_accountDb = openDatabase(dbPath);
}

Expand All @@ -29,7 +29,9 @@ export function listLoginMethods() {
const rows = accountDb.all('SELECT method, display_name, active FROM auth');
return rows
.filter(f =>
rows.length > 1 && config.enforceOpenId ? f.method === 'openid' : true,
rows.length > 1 && config.get('enforceOpenId')
? f.method === 'openid'
: true,
)
.map(r => ({
method: r.method,
Expand All @@ -55,13 +57,13 @@ export function getLoginMethod(req) {
if (
typeof req !== 'undefined' &&
(req.body || { loginMethod: null }).loginMethod &&
config.allowedLoginMethods.includes(req.body.loginMethod)
config.get('allowedLoginMethods').includes(req.body.loginMethod)
) {
return req.body.loginMethod;
}

if (config.loginMethod) {
return config.loginMethod;
if (config.get('loginMethod')) {
return config.get('loginMethod');
}

const activeMethod = getActiveLoginMethod();
Expand Down
61 changes: 30 additions & 31 deletions packages/sync-server/src/accounts/openid.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@ import { generators, Issuer } from 'openid-client';
import { v4 as uuidv4 } from 'uuid';

import { clearExpiredSessions, getAccountDb } from '../account-db.js';
import { config as finalConfig } from '../load-config.js';
import { config } from '../load-config.js';
import {
getUserByUsername,
transferAllFilesFromUser,
} from '../services/user-service.js';
import { TOKEN_EXPIRATION_NEVER } from '../util/validate-user.js';

export async function bootstrapOpenId(config) {
if (!('issuer' in config)) {
return { error: 'missing-issuer' };
export async function bootstrapOpenId(configParameter) {
if (!('issuer' in configParameter) || !('discoveryURL' in configParameter)) {
return { error: 'missing-issuer-or-discoveryURL' };
}
if (!('client_id' in config)) {
if (!('client_id' in configParameter)) {
return { error: 'missing-client-id' };
}
if (!('client_secret' in config)) {
if (!('client_secret' in configParameter)) {
return { error: 'missing-client-secret' };
}
if (!('server_hostname' in config)) {
if (!('server_hostname' in configParameter)) {
return { error: 'missing-server-hostname' };
}

try {
await setupOpenIdClient(config);
await setupOpenIdClient(configParameter);
} catch (err) {
console.error('Error setting up OpenID client:', err);
return { error: 'configuration-error' };
Expand All @@ -37,7 +37,7 @@ export async function bootstrapOpenId(config) {
accountDb.mutate('UPDATE auth SET active = 0');
accountDb.mutate(
"INSERT INTO auth (method, display_name, extra_data, active) VALUES ('openid', 'OpenID', ?, 1)",
[JSON.stringify(config)],
[JSON.stringify(configParameter)],
);
});
} catch (err) {
Expand All @@ -48,23 +48,22 @@ export async function bootstrapOpenId(config) {
return {};
}

async function setupOpenIdClient(config) {
const issuer =
typeof config.issuer === 'string'
? await Issuer.discover(config.issuer)
: new Issuer({
issuer: config.issuer.name,
authorization_endpoint: config.issuer.authorization_endpoint,
token_endpoint: config.issuer.token_endpoint,
userinfo_endpoint: config.issuer.userinfo_endpoint,
});
async function setupOpenIdClient(configParameter) {
const issuer = configParameter.discoveryURL
? await Issuer.discover(configParameter.discoveryURL)
: new Issuer({
issuer: configParameter.issuer.name,
authorization_endpoint: configParameter.issuer.authorization_endpoint,
token_endpoint: configParameter.issuer.token_endpoint,
userinfo_endpoint: configParameter.issuer.userinfo_endpoint,
});

const client = new issuer.Client({
client_id: config.client_id,
client_secret: config.client_secret,
client_id: configParameter.client_id,
client_secret: configParameter.client_secret,
redirect_uri: new URL(
'/openid/callback',
config.server_hostname,
configParameter.server_hostname,
).toString(),
validate_id_token: true,
});
Expand Down Expand Up @@ -139,21 +138,21 @@ export async function loginWithOpenIdFinalize(body) {
}

const accountDb = getAccountDb();
let config = accountDb.first(
let configFromDb = accountDb.first(
"SELECT extra_data FROM auth WHERE method = 'openid' AND active = 1",
);
if (!config) {
if (!configFromDb) {
return { error: 'openid-not-configured' };
}
try {
config = JSON.parse(config['extra_data']);
configFromDb = JSON.parse(configFromDb['extra_data']);
} catch (err) {
console.error('Error parsing OpenID configuration:', err);
return { error: 'openid-setup-failed' };
}
let client;
try {
client = await setupOpenIdClient(config);
client = await setupOpenIdClient(configFromDb);
} catch (err) {
console.error('Error setting up OpenID client:', err);
return { error: 'openid-setup-failed' };
Expand All @@ -173,7 +172,7 @@ export async function loginWithOpenIdFinalize(body) {
try {
let tokenSet = null;

if (!config.authMethod || config.authMethod === 'openid') {
if (!configFromDb.authMethod || configFromDb.authMethod === 'openid') {
const params = { code: body.code, state: body.state };
tokenSet = await client.callback(client.redirect_uris[0], params, {
code_verifier,
Expand Down Expand Up @@ -264,13 +263,13 @@ export async function loginWithOpenIdFinalize(body) {
const token = uuidv4();

let expiration;
if (finalConfig.token_expiration === 'openid-provider') {
if (config.get('token_expiration') === 'openid-provider') {
expiration = tokenSet.expires_at ?? TOKEN_EXPIRATION_NEVER;
} else if (finalConfig.token_expiration === 'never') {
} else if (config.get('token_expiration') === 'never') {
expiration = TOKEN_EXPIRATION_NEVER;
} else if (typeof finalConfig.token_expiration === 'number') {
} else if (typeof config.get('token_expiration') === 'number') {
expiration =
Math.floor(Date.now() / 1000) + finalConfig.token_expiration * 60;
Math.floor(Date.now() / 1000) + config.get('token_expiration') * 60;
} else {
expiration = Math.floor(Date.now() / 1000) + 10 * 60;
}
Expand Down
9 changes: 5 additions & 4 deletions packages/sync-server/src/accounts/password.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ export function loginWithPassword(password) {

let expiration = TOKEN_EXPIRATION_NEVER;
if (
config.token_expiration !== 'never' &&
config.token_expiration !== 'openid-provider' &&
typeof config.token_expiration === 'number'
config.get('token_expiration') !== 'never' &&
config.get('token_expiration') !== 'openid-provider' &&
typeof config.get('token_expiration') === 'number'
) {
expiration = Math.floor(Date.now() / 1000) + config.token_expiration * 60;
expiration =
Math.floor(Date.now() / 1000) + config.get('token_expiration') * 60;
}

if (!sessionRow) {
Expand Down
34 changes: 21 additions & 13 deletions packages/sync-server/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ process.on('unhandledRejection', reason => {

app.disable('x-powered-by');
app.use(cors());
app.set('trust proxy', config.trustedProxies);
app.set('trust proxy', config.get('trustedProxies'));
if (process.env.NODE_ENV !== 'development') {
app.use(
rateLimit({
Expand All @@ -35,17 +35,19 @@ if (process.env.NODE_ENV !== 'development') {
);
}

app.use(bodyParser.json({ limit: `${config.upload.fileSizeLimitMB}mb` }));
app.use(
bodyParser.json({ limit: `${config.get('upload.fileSizeLimitMB')}mb` }),
);
app.use(
bodyParser.raw({
type: 'application/actual-sync',
limit: `${config.upload.fileSizeSyncLimitMB}mb`,
limit: `${config.get('upload.fileSizeSyncLimitMB')}mb`,
}),
);
app.use(
bodyParser.raw({
type: 'application/encrypted-file',
limit: `${config.upload.syncEncryptedFileSizeLimitMB}mb`,
limit: `${config.get('upload.syncEncryptedFileSizeLimitMB')}mb`,
}),
);

Expand All @@ -59,7 +61,7 @@ app.use('/admin', adminApp.handlers);
app.use('/openid', openidApp.handlers);

app.get('/mode', (req, res) => {
res.send(config.mode);
res.send(config.get('mode'));
});

app.use(actuator()); // Provides /health, /metrics, /info
Expand Down Expand Up @@ -89,8 +91,10 @@ if (process.env.NODE_ENV === 'development') {
} else {
console.log('Running in production mode - Serving static React app');

app.use(express.static(config.webRoot, { index: false }));
app.get('/*', (req, res) => res.sendFile(config.webRoot + '/index.html'));
app.use(express.static(config.get('webRoot'), { index: false }));
app.get('/*', (req, res) =>
res.sendFile(config.get('webRoot') + '/index.html'),
);
}

function parseHTTPSConfig(value) {
Expand All @@ -101,17 +105,21 @@ function parseHTTPSConfig(value) {
}

export async function run() {
if (config.https) {
if (config.get('https.key') && config.get('https.cert')) {
const https = await import('node:https');
const httpsOptions = {
...config.https,
key: parseHTTPSConfig(config.https.key),
cert: parseHTTPSConfig(config.https.cert),
key: parseHTTPSConfig(config.get('https.key')),
cert: parseHTTPSConfig(config.get('https.cert')),
};
https.createServer(httpsOptions, app).listen(config.port, config.hostname);
https
.createServer(httpsOptions, app)
.listen(config.get('port'), config.get('hostname'));
} else {
app.listen(config.port, config.hostname);
app.listen(config.get('port'), config.get('hostname'));
}

console.log('Listening on ' + config.hostname + ':' + config.port + '...');
console.log(
'Listening on ' + config.get('hostname') + ':' + config.get('port') + '...',
);
}
1 change: 0 additions & 1 deletion packages/sync-server/src/config-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export interface Config {
server_hostname: string;
authMethod?: 'openid' | 'oauth2';
};
multiuser: boolean;
token_expiration?: 'never' | 'openid-provider' | number;
enforceOpenId: boolean;
}
Loading

0 comments on commit 8d1b5c7

Please sign in to comment.