login
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Body, Controller, Get, Param, Post, Req, Res } from '@nestjs/common';
|
||||
import { Body, Controller, Get, Param, Post, Req, Res, UnauthorizedException } from '@nestjs/common';
|
||||
import { Request, Response } from 'express';
|
||||
import { OidcProviderService } from './oidc-provider.service';
|
||||
|
||||
@@ -10,7 +10,7 @@ export class OidcInteractionController {
|
||||
async view(@Param('uid') uid: string, @Req() request: Request, @Res() response: Response) {
|
||||
const details = await this.oidc.interactionDetails(request, response);
|
||||
if (details.uid !== uid) {
|
||||
response.status(400).send(this.page('Ungueltige Anfrage', '<p>Die OIDC-Interaktion ist ungueltig.</p>'));
|
||||
response.status(400).send(this.page('Ungültige Anfrage', '<p>Die OIDC-Interaktion ist ungültig.</p>'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -18,16 +18,7 @@ export class OidcInteractionController {
|
||||
response.send(
|
||||
this.page(
|
||||
'Anmelden',
|
||||
`
|
||||
<form method="post" action="/interaction/${encodeURIComponent(uid)}/login">
|
||||
<label>Benutzername <input name="username" autocomplete="username" required></label>
|
||||
<label>Passwort <input name="password" type="password" autocomplete="current-password" required></label>
|
||||
<button type="submit">Anmelden</button>
|
||||
</form>
|
||||
<form method="post" action="/interaction/${encodeURIComponent(uid)}/abort">
|
||||
<button class="secondary" type="submit">Abbrechen</button>
|
||||
</form>
|
||||
`,
|
||||
this.loginForm(uid),
|
||||
),
|
||||
);
|
||||
return;
|
||||
@@ -38,7 +29,7 @@ export class OidcInteractionController {
|
||||
this.page(
|
||||
'Zugriff erlauben',
|
||||
`
|
||||
<p>Client <strong>${this.escape(String(details.params.client_id ?? ''))}</strong> moechte Zugriff auf folgende Scopes:</p>
|
||||
<p>Client <strong>${this.escape(String(details.params.name ?? ''))}</strong> möchte Zugriff auf folgende Scopes:</p>
|
||||
<p class="scopes">${this.escape(String(details.params.scope ?? 'openid'))}</p>
|
||||
<form method="post" action="/interaction/${encodeURIComponent(uid)}/confirm">
|
||||
<button type="submit">Erlauben</button>
|
||||
@@ -62,7 +53,19 @@ export class OidcInteractionController {
|
||||
@Req() request: Request,
|
||||
@Res() response: Response,
|
||||
) {
|
||||
await this.oidc.finishLogin(request, response, uid, body.username ?? '', body.password ?? '');
|
||||
const username = body.username ?? '';
|
||||
try {
|
||||
await this.oidc.finishLogin(request, response, uid, username, body.password ?? '');
|
||||
} catch (error) {
|
||||
if (this.isInvalidCredentialsError(error)) {
|
||||
response
|
||||
.status(401)
|
||||
.send(this.page('Anmelden', this.loginForm(uid, username, 'Ungültige Zugangsdaten.')));
|
||||
return;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@Post(':uid/confirm')
|
||||
@@ -75,6 +78,25 @@ export class OidcInteractionController {
|
||||
await this.oidc.abortInteraction(request, response);
|
||||
}
|
||||
|
||||
private loginForm(uid: string, username = '', errorMessage = ''): string {
|
||||
const encodedUid = encodeURIComponent(uid);
|
||||
const error = errorMessage
|
||||
? `<p class="message error" role="alert">${this.escape(errorMessage)}</p>`
|
||||
: '';
|
||||
|
||||
return `
|
||||
${error}
|
||||
<form method="post" action="/interaction/${encodedUid}/login">
|
||||
<label>Benutzername <input name="username" autocomplete="username" value="${this.escape(username)}" required></label>
|
||||
<label>Passwort <input name="password" type="password" autocomplete="current-password" required autofocus></label>
|
||||
<button type="submit">Anmelden</button>
|
||||
</form>
|
||||
<form method="post" action="/interaction/${encodedUid}/abort">
|
||||
<button class="secondary" type="submit">Abbrechen</button>
|
||||
</form>
|
||||
`;
|
||||
}
|
||||
|
||||
private page(title: string, body: string): string {
|
||||
return `<!doctype html>
|
||||
<html lang="de">
|
||||
@@ -91,6 +113,8 @@ export class OidcInteractionController {
|
||||
input { border: 1px solid #bcc8d3; border-radius: 6px; font: inherit; min-height: 44px; padding: 10px 12px; }
|
||||
button { background: #0f6b6e; border: 1px solid #0f6b6e; border-radius: 6px; color: white; cursor: pointer; font: inherit; font-weight: 700; min-height: 44px; padding: 10px 14px; }
|
||||
button.secondary { background: white; color: #0f6b6e; }
|
||||
.message { background: #edf7f4; border: 1px solid #b8ddd3; border-radius: 6px; color: #24564f; margin: 0 0 16px; padding: 12px; }
|
||||
.message.error { background: #fff1f0; border-color: #efb5ae; color: #8d2b20; }
|
||||
.scopes { background: #edf2f5; border-radius: 6px; padding: 10px; word-break: break-word; }
|
||||
</style>
|
||||
</head>
|
||||
@@ -106,4 +130,8 @@ export class OidcInteractionController {
|
||||
.replaceAll('"', '"')
|
||||
.replaceAll("'", ''');
|
||||
}
|
||||
|
||||
private isInvalidCredentialsError(error: unknown): boolean {
|
||||
return error instanceof UnauthorizedException && error.message === 'Ungültige Zugangsdaten.';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user