1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-12-09 20:04:11 +01:00
unleash.unleash/src/lib/middleware/demo-authentication.ts
00Chaotic 13aa58e0e9
feat: allow admin login using demo auth (#6808)
This PR introduces a configuration option (`authentication.demoAllowAdminLogin`) that allows you to log in as admin when using demo authentication. To do this, use the username `admin`. 

## About the changes
The `admin` user currently cannot be accessed in `demo` authentication
mode, as the auth mode requires only an email to log in, and the admin
user is not created with an email. This change allows for logging in as
the admin user only if an `AUTH_DEMO_ALLOW_ADMIN_LOGIN` is set to `true`
(or the corresponding `authDemoAllowAdminLogin` config is enabled).

<!-- Does it close an issue? Multiple? -->
Closes #6398 

### Important files

[demo-authentication.ts](https://github.com/Unleash/unleash/compare/main...00Chaotic:unleash:feat/allow_admin_login_using_demo_auth?expand=1#diff-c166f00f0a8ca4425236b3bcba40a8a3bd07a98d067495a0a092eec26866c9f1R25)


## Discussion points
Can continue discussion of [this
comment](https://github.com/Unleash/unleash/pull/6447#issuecomment-2042405647)
in this PR.

---------

Co-authored-by: Thomas Heartman <thomasheartman+github@gmail.com>
2024-04-23 08:39:33 +02:00

84 lines
2.7 KiB
TypeScript

import type { Application } from 'express';
import AuthenticationRequired from '../types/authentication-required';
import type { IUnleashServices } from '../types/services';
import type { IUnleashConfig } from '../types/option';
import ApiUser from '../types/api-user';
import { ApiTokenType } from '../types/models/api-token';
import type { IAuthRequest, IUser } from '../server-impl';
import type { IApiRequest } from '../routes/unleash-types';
import { encrypt } from '../util';
function demoAuthentication(
app: Application,
basePath: string,
{ userService }: Pick<IUnleashServices, 'userService'>,
{
authentication,
flagResolver,
}: Pick<IUnleashConfig, 'authentication' | 'flagResolver'>,
): void {
app.post(`${basePath}/auth/demo/login`, async (req: IAuthRequest, res) => {
let { email } = req.body;
let user: IUser;
try {
if (authentication.demoAllowAdminLogin && email === 'admin') {
user = await userService.loginDemoAuthDefaultAdmin();
} else {
email = flagResolver.isEnabled('encryptEmails', { email })
? encrypt(email)
: email;
user = await userService.loginUserWithoutPassword(email, true);
}
req.session.user = user;
return res.status(200).json(user);
} catch (e) {
res.status(400)
.json({ error: `Could not sign in with ${email}` })
.end();
}
});
app.use(`${basePath}/api/admin/`, (req: IAuthRequest, res, next) => {
if (req.session.user?.email || req.session.user?.username === 'admin') {
req.user = req.session.user;
}
next();
});
app.use(`${basePath}/api/client`, (req: IApiRequest, res, next) => {
if (!authentication.enableApiToken && !req.user) {
req.user = new ApiUser({
tokenName: 'unauthed-default-client',
permissions: [],
environment: 'default',
type: ApiTokenType.CLIENT,
project: '*',
secret: 'a',
});
}
next();
});
app.use(`${basePath}/api`, (req: IAuthRequest, res, next) => {
if (req.user) {
return next();
}
return res
.status(401)
.json(
new AuthenticationRequired({
path: `${basePath}/auth/demo/login`,
type: 'demo',
message:
'You have to identify yourself in order to use Unleash.',
}),
)
.end();
});
}
export default demoAuthentication;