mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-21 17:26:29 -05:00
Feature/open id sign in (#35)
* added errorOpenIdLogin i18n key * added openid authProvider * added postOpenIdLogin api call * added via-open-id component Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
parent
d2c6ea464d
commit
a50ad6e6c8
8 changed files with 92 additions and 9 deletions
|
@ -10,12 +10,13 @@
|
||||||
"google": true,
|
"google": true,
|
||||||
"saml": true,
|
"saml": true,
|
||||||
"oauth2": true,
|
"oauth2": true,
|
||||||
"email": true
|
"email": true,
|
||||||
|
"openid": true
|
||||||
},
|
},
|
||||||
"customAuthNames": {
|
"customAuthNames": {
|
||||||
"ldap": "FooBar",
|
"ldap": "FooBar",
|
||||||
"saml": "aufSAMLn.de",
|
"oauth2": "Olaf2",
|
||||||
"oauth2": "Olaf2"
|
"saml": "aufSAMLn.de"
|
||||||
},
|
},
|
||||||
"specialLinks": {
|
"specialLinks": {
|
||||||
"privacy": "test",
|
"privacy": "test",
|
||||||
|
|
|
@ -123,5 +123,6 @@
|
||||||
"errorLdapLogin": "Benutzername oder Passwort nicht korrekt",
|
"errorLdapLogin": "Benutzername oder Passwort nicht korrekt",
|
||||||
"email": "E-Mail",
|
"email": "E-Mail",
|
||||||
"password": "Passwort",
|
"password": "Passwort",
|
||||||
"username": "Benutzername"
|
"username": "Benutzername",
|
||||||
|
"errorOpenIdLogin": "OpenID nicht korrekt"
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,5 +123,6 @@
|
||||||
"errorLdapLogin": "Invalid username or password",
|
"errorLdapLogin": "Invalid username or password",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"username": "Username"
|
"username": "Username",
|
||||||
|
"errorOpenIdLogin": "Invalid OpenID provided"
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,3 +43,22 @@ export const postLdapLogin = async (username: string, password: string) => {
|
||||||
.then(expectResponseCode())
|
.then(expectResponseCode())
|
||||||
.then(response => response.json());
|
.then(response => response.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const postOpenIdLogin = async (openId: string) => {
|
||||||
|
return fetch(getBackendUrl() + "/auth/openid", {
|
||||||
|
method: 'POST',
|
||||||
|
mode: 'cors',
|
||||||
|
cache: 'no-cache',
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
redirect: 'follow',
|
||||||
|
referrerPolicy: 'no-referrer',
|
||||||
|
body: JSON.stringify({
|
||||||
|
openId: openId
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(expectResponseCode())
|
||||||
|
.then(response => response.json());
|
||||||
|
}
|
||||||
|
|
54
src/components/landing/pages/login/auth/via-open id.tsx
Normal file
54
src/components/landing/pages/login/auth/via-open id.tsx
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import React, {Fragment, useState} from "react";
|
||||||
|
import {Trans, useTranslation} from "react-i18next";
|
||||||
|
import {Alert, Button, Form} from "react-bootstrap";
|
||||||
|
import {postOpenIdLogin} from "../../../../../api/user";
|
||||||
|
import {getAndSetUser} from "../../../../../utils/apiUtils";
|
||||||
|
|
||||||
|
const ViaOpenId: React.FC = () => {
|
||||||
|
useTranslation();
|
||||||
|
const [openId, setOpenId] = useState("");
|
||||||
|
const [error, setError] = useState(false);
|
||||||
|
const login = (event: any) => {
|
||||||
|
postOpenIdLogin(openId)
|
||||||
|
.then(loginJson => {
|
||||||
|
console.log(loginJson)
|
||||||
|
getAndSetUser();
|
||||||
|
}).catch(_reason => {
|
||||||
|
setError(true);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<h5 className="center">
|
||||||
|
<Trans i18nKey="signInVia" values={{service: "OpenID"}}/>
|
||||||
|
</h5>
|
||||||
|
<Form onSubmit={login}>
|
||||||
|
<Form.Group controlId="openid">
|
||||||
|
<Form.Control
|
||||||
|
isInvalid={error}
|
||||||
|
type="text"
|
||||||
|
size="sm"
|
||||||
|
placeholder={"OpenID"}
|
||||||
|
onChange={(event) => setOpenId(event.currentTarget.value)}
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
|
||||||
|
<Alert className="small" show={error} variant="danger">
|
||||||
|
<Trans i18nKey="errorOpenIdLogin"/>
|
||||||
|
</Alert>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
size="sm"
|
||||||
|
variant="primary">
|
||||||
|
<Trans i18nKey="signIn"/>
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { ViaOpenId }
|
|
@ -6,6 +6,7 @@ import {OneClickType, ViaOneClick} from "./auth/via-one-click";
|
||||||
import {ViaLdap} from "./auth/via-ldap";
|
import {ViaLdap} from "./auth/via-ldap";
|
||||||
import {useSelector} from "react-redux";
|
import {useSelector} from "react-redux";
|
||||||
import {ApplicationState} from "../../../../redux";
|
import {ApplicationState} from "../../../../redux";
|
||||||
|
import {ViaOpenId} from "./auth/via-open id";
|
||||||
|
|
||||||
const Login: React.FC = () => {
|
const Login: React.FC = () => {
|
||||||
useTranslation();
|
useTranslation();
|
||||||
|
@ -13,7 +14,9 @@ const Login: React.FC = () => {
|
||||||
const customAuthNames = useSelector((state: ApplicationState) => state.backendConfig.customAuthNames);
|
const customAuthNames = useSelector((state: ApplicationState) => state.backendConfig.customAuthNames);
|
||||||
const emailForm = authProviders.email ? <ViaEMail/> : null
|
const emailForm = authProviders.email ? <ViaEMail/> : null
|
||||||
const ldapForm = authProviders.ldap ? <ViaLdap/> : null
|
const ldapForm = authProviders.ldap ? <ViaLdap/> : null
|
||||||
|
const openIdForm = authProviders.openid ? <ViaOpenId/> : null
|
||||||
const emailLdapSeparator = authProviders.email && authProviders.ldap ? <hr className="w-100 bg-white"/> : null
|
const emailLdapSeparator = authProviders.email && authProviders.ldap ? <hr className="w-100 bg-white"/> : null
|
||||||
|
const ldapOpenIdSeparator = authProviders.ldap && authProviders.openid ? <hr className="w-100 bg-white"/> : null
|
||||||
|
|
||||||
const oneClickCustomName: (type: OneClickType) => string | undefined = (type) => {
|
const oneClickCustomName: (type: OneClickType) => string | undefined = (type) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -36,6 +39,8 @@ const Login: React.FC = () => {
|
||||||
{emailForm}
|
{emailForm}
|
||||||
{emailLdapSeparator}
|
{emailLdapSeparator}
|
||||||
{ldapForm}
|
{ldapForm}
|
||||||
|
{ldapOpenIdSeparator}
|
||||||
|
{openIdForm}
|
||||||
<hr className="w-100 d-lg-none d-block bg-white"/>
|
<hr className="w-100 d-lg-none d-block bg-white"/>
|
||||||
</Col>
|
</Col>
|
||||||
: null
|
: null
|
||||||
|
|
|
@ -13,12 +13,13 @@ export const initialState: BackendConfigState = {
|
||||||
google: false,
|
google: false,
|
||||||
saml: false,
|
saml: false,
|
||||||
oauth2: false,
|
oauth2: false,
|
||||||
email: false
|
email: false,
|
||||||
|
openid: false
|
||||||
},
|
},
|
||||||
customAuthNames: {
|
customAuthNames: {
|
||||||
ldap: "",
|
ldap: "",
|
||||||
saml: "",
|
oauth2: "",
|
||||||
oauth2: ""
|
saml: ""
|
||||||
},
|
},
|
||||||
specialLinks: {
|
specialLinks: {
|
||||||
privacy: "",
|
privacy: "",
|
||||||
|
|
|
@ -20,12 +20,13 @@ export interface AuthProvidersState {
|
||||||
saml: boolean,
|
saml: boolean,
|
||||||
oauth2: boolean,
|
oauth2: boolean,
|
||||||
email: boolean,
|
email: boolean,
|
||||||
|
openid: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CustomAuthNames {
|
export interface CustomAuthNames {
|
||||||
ldap: string;
|
ldap: string;
|
||||||
saml: string;
|
|
||||||
oauth2: string;
|
oauth2: string;
|
||||||
|
saml: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SpecialLinks {
|
export interface SpecialLinks {
|
||||||
|
|
Loading…
Reference in a new issue