2024-03-23 17:11:06 +00:00
|
|
|
import {ApiError} from 'app/common/ApiError';
|
2024-05-23 20:40:31 +00:00
|
|
|
import {HomeDBManager} from 'app/gen-server/lib/HomeDBManager';
|
2024-03-23 17:11:06 +00:00
|
|
|
import {appSettings} from 'app/server/lib/AppSettings';
|
|
|
|
import {getUser, RequestWithLogin} from 'app/server/lib/Authorizer';
|
|
|
|
import {User} from 'app/gen-server/entity/User';
|
|
|
|
import express from 'express';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class implementing the logic to determine whether a user is authorized to manage the Grist
|
|
|
|
* installation.
|
|
|
|
*/
|
|
|
|
export abstract class InstallAdmin {
|
|
|
|
|
|
|
|
// Returns true if user is authorized to manage the Grist installation.
|
|
|
|
public abstract isAdminUser(user: User): Promise<boolean>;
|
|
|
|
|
|
|
|
// Returns true if req is authenticated (contains a user) and the user is authorized to manage
|
|
|
|
// the Grist installation. This should not fail, only return true or false.
|
|
|
|
public async isAdminReq(req: express.Request): Promise<boolean> {
|
|
|
|
const user = (req as RequestWithLogin).user;
|
|
|
|
return user ? this.isAdminUser(user) : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns middleware that fails unless the request includes an authenticated user and this user
|
|
|
|
// is authorized to manage the Grist installation.
|
|
|
|
public getMiddlewareRequireAdmin(): express.RequestHandler {
|
|
|
|
return this._requireAdmin.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
private async _requireAdmin(req: express.Request, resp: express.Response, next: express.NextFunction) {
|
|
|
|
try {
|
|
|
|
// getUser() will fail with 401 if user is not present.
|
|
|
|
if (!await this.isAdminUser(getUser(req))) {
|
|
|
|
throw new ApiError('Access denied', 403);
|
|
|
|
}
|
|
|
|
next();
|
|
|
|
} catch (err) {
|
|
|
|
next(err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Considers the user whose email matches GRIST_DEFAULT_EMAIL env var, if given, to be the
|
2024-05-23 20:40:31 +00:00
|
|
|
// installation admin. The support user is also accepted.
|
|
|
|
// Otherwise, there is no admin.
|
2024-03-23 17:11:06 +00:00
|
|
|
export class SimpleInstallAdmin extends InstallAdmin {
|
|
|
|
private _installAdminEmail = appSettings.section('access').flag('installAdminEmail').readString({
|
|
|
|
envVar: 'GRIST_DEFAULT_EMAIL',
|
|
|
|
});
|
|
|
|
|
2024-05-23 20:40:31 +00:00
|
|
|
public constructor(private _dbManager: HomeDBManager) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2024-03-23 17:11:06 +00:00
|
|
|
public override async isAdminUser(user: User): Promise<boolean> {
|
2024-05-23 20:40:31 +00:00
|
|
|
if (user.id === this._dbManager.getSupportUserId()) { return true; }
|
2024-03-23 17:11:06 +00:00
|
|
|
return this._installAdminEmail ? (user.loginEmail === this._installAdminEmail) : false;
|
|
|
|
}
|
|
|
|
}
|