11 changed files with 267 additions and 87 deletions
@ -1,42 +1,43 @@
@@ -1,42 +1,43 @@
|
||||
{ |
||||
"User not found": "Benutzer nicht gefunden", |
||||
"Password or username wrong": "Passwort oder Benutzername falsch", |
||||
"Authorize %s": "Authorize %s", |
||||
"Login": "Einloggen", |
||||
"You are not logged in or your login is expired": "Du bist nicht länger angemeldet oder deine Anmeldung ist abgelaufen.", |
||||
"Username or Email": "Benutzername oder Email", |
||||
"Password": "Passwort", |
||||
"Next": "Weiter", |
||||
"Register": "Registrieren", |
||||
"Mail": "Mail", |
||||
"Repeat Password": "Passwort wiederholen", |
||||
"Username": "Benutzername", |
||||
"Name": "Name", |
||||
"Registration code": "Registrierungs Schlüssel", |
||||
"You need to select one of the options": "Du musst eine der Optionen auswälen", |
||||
"Male": "Mann", |
||||
"Female": "Frau", |
||||
"Other": "Anderes", |
||||
"Registration code required": "Registrierungs Schlüssel benötigt", |
||||
"Username required": "Benutzername benötigt", |
||||
"Name required": "Name benötigt", |
||||
"Mail required": "Mail benötigt", |
||||
"The passwords do not match": "Die Passwörter stimmen nicht überein", |
||||
"Password is required": "Password benötigt", |
||||
"Invalid registration code": "Ungültiger Registrierungs Schlüssel", |
||||
"Username taken": "Benutzername nicht verfügbar", |
||||
"Mail linked with other account": "Mail ist bereits mit einem anderen Account verbunden", |
||||
"Registration code already used": "Registrierungs Schlüssel wurde bereits verwendet", |
||||
"Administration": "Administration", |
||||
"Field {{field}} is not defined": "Feld {{field}} fehlt", |
||||
"Field {{field}} has wrong type. It should be from type {{type}}": "Feld {{field}} hat den falschen Typ. Es sollte vom Typ {{type}} sein", |
||||
"Client has no permission for acces password auth": "Dieser Client hat keine Berechtigung password auth zu benutzen", |
||||
"Invalid token": "Ungültiger Token", |
||||
"By clicking on ALLOW, you allow this app to access the requested recources.": "Wenn sie ALLOW drücken, berechtigen sie die Applikation die beantragten Resourcen zu benutzen.", |
||||
"User": "User", |
||||
"No special token": "No special token", |
||||
"Login token invalid": "Login token invalid", |
||||
"No login token": "No login token", |
||||
"You are not logged in or your login is expired (Login token invalid)": "You are not logged in or your login is expired (Login token invalid)", |
||||
"You are not logged in or your login is expired (No special token)": "You are not logged in or your login is expired (No special token)" |
||||
} |
||||
"User not found": "Benutzer nicht gefunden", |
||||
"Password or username wrong": "Passwort oder Benutzername falsch", |
||||
"Authorize %s": "Authorize %s", |
||||
"Login": "Einloggen", |
||||
"You are not logged in or your login is expired": "Du bist nicht länger angemeldet oder deine Anmeldung ist abgelaufen.", |
||||
"Username or Email": "Benutzername oder Email", |
||||
"Password": "Passwort", |
||||
"Next": "Weiter", |
||||
"Register": "Registrieren", |
||||
"Mail": "Mail", |
||||
"Repeat Password": "Passwort wiederholen", |
||||
"Username": "Benutzername", |
||||
"Name": "Name", |
||||
"Registration code": "Registrierungs Schlüssel", |
||||
"You need to select one of the options": "Du musst eine der Optionen auswälen", |
||||
"Male": "Mann", |
||||
"Female": "Frau", |
||||
"Other": "Anderes", |
||||
"Registration code required": "Registrierungs Schlüssel benötigt", |
||||
"Username required": "Benutzername benötigt", |
||||
"Name required": "Name benötigt", |
||||
"Mail required": "Mail benötigt", |
||||
"The passwords do not match": "Die Passwörter stimmen nicht überein", |
||||
"Password is required": "Password benötigt", |
||||
"Invalid registration code": "Ungültiger Registrierungs Schlüssel", |
||||
"Username taken": "Benutzername nicht verfügbar", |
||||
"Mail linked with other account": "Mail ist bereits mit einem anderen Account verbunden", |
||||
"Registration code already used": "Registrierungs Schlüssel wurde bereits verwendet", |
||||
"Administration": "Administration", |
||||
"Field {{field}} is not defined": "Feld {{field}} fehlt", |
||||
"Field {{field}} has wrong type. It should be from type {{type}}": "Feld {{field}} hat den falschen Typ. Es sollte vom Typ {{type}} sein", |
||||
"Client has no permission for acces password auth": "Dieser Client hat keine Berechtigung password auth zu benutzen", |
||||
"Invalid token": "Ungültiger Token", |
||||
"By clicking on ALLOW, you allow this app to access the requested recources.": "Wenn sie ALLOW drücken, berechtigen sie die Applikation die beantragten Resourcen zu benutzen.", |
||||
"User": "User", |
||||
"No special token": "No special token", |
||||
"Login token invalid": "Login token invalid", |
||||
"No login token": "No login token", |
||||
"You are not logged in or your login is expired (Login token invalid)": "You are not logged in or your login is expired (Login token invalid)", |
||||
"You are not logged in or your login is expired (No special token)": "You are not logged in or your login is expired (No special token)", |
||||
"Special token invalid": "Special token invalid" |
||||
} |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
import { Request, Response } from "express"; |
||||
import Stacker from "../middlewares/stacker"; |
||||
import { GetUserMiddleware } from "../middlewares/user"; |
||||
import { URL } from "url"; |
||||
import Client from "../../models/client"; |
||||
import RequestError, { HttpStatusCode } from "../../helper/request_error"; |
||||
import { getAccessTokenJWT } from "../../helper/jwt"; |
||||
|
||||
export const GetJWTByUser = Stacker( |
||||
GetUserMiddleware(true, false), |
||||
async (req: Request, res: Response) => { |
||||
const { client_id, origin } = req.query as { [key: string]: string }; |
||||
|
||||
const client = await Client.findOne({ |
||||
client_id, |
||||
}); |
||||
|
||||
const clientNotFoundError = new RequestError( |
||||
"Client not found!", |
||||
HttpStatusCode.BAD_REQUEST |
||||
); |
||||
|
||||
if (!client) throw clientNotFoundError; |
||||
|
||||
const clientUrl = new URL(client.redirect_url); |
||||
|
||||
if (clientUrl.hostname !== origin) throw clientNotFoundError; |
||||
|
||||
const jwt = await getAccessTokenJWT({ |
||||
user: req.user, |
||||
client: client, |
||||
permissions: [], |
||||
}); |
||||
|
||||
res.json({ jwt }); |
||||
} |
||||
); |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
import * as handlebars from "handlebars"; |
||||
import { readFileSync } from "fs"; |
||||
import { __ as i__ } from "i18n"; |
||||
import config from "../config"; |
||||
|
||||
let template: handlebars.TemplateDelegate<any>; |
||||
function loadStatic() { |
||||
let html = readFileSync("./views/out/popup/popup.html").toString(); |
||||
template = handlebars.compile(html); |
||||
} |
||||
|
||||
export default function GetPopupPage(__: typeof i__): string { |
||||
if (config.core.dev) { |
||||
loadStatic(); |
||||
} |
||||
|
||||
let data = {}; |
||||
return template(data, { helpers: { i18n: __ } }); |
||||
} |
||||
|
||||
loadStatic(); |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
<html> |
||||
|
||||
|
||||
<head> |
||||
<title>Popup Auth</title> |
||||
<meta charset="utf8" /> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1" /> |
||||
</head> |
||||
|
||||
<body> |
||||
<div class="card"> |
||||
<div class="title"> |
||||
<h1>Allow <span id="hostname" style="font-weight: bold;">LOADING...</span> to authenticate you?</h1> |
||||
</div> |
||||
<div> |
||||
<div style="text-align: right;"> |
||||
<button onclick="allow()" class="mdc-button mdc-button--raised blue-button">Allow</button> |
||||
<button onclick="deny()" class="mdc-button mdc-button--raised blue-button">Deny</button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</body> |
||||
|
||||
</html> |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
async function getJWT(client_id, hostname) { |
||||
hostname = encodeURIComponent(hostname); |
||||
client_id = encodeURIComponent(client_id); |
||||
|
||||
const res = await fetch( |
||||
`/api/user/jwt?client_id=${client_id}&origin=${hostname}` |
||||
).then((res) => res.json()); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
let acceptPromise; |
||||
|
||||
window.allow = () => acceptPromise(); |
||||
window.deny = () => window.close(); |
||||
|
||||
function start() { |
||||
let started = false; |
||||
window.addEventListener("message", async (msg) => { |
||||
if (!started) { |
||||
started = true; |
||||
const url = new URL(msg.origin); |
||||
document.getElementById("hostname").innerText = url.hostname; |
||||
await new Promise((yes) => (acceptPromise = yes)); |
||||
const res = await getJWT(msg.data.client_id, url.hostname); |
||||
msg.source.postMessage(res, msg.origin); |
||||
window.close(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
start(); |
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
@import "@material/button/mdc-button"; |
||||
.blue-button { |
||||
background: #4a89dc !important; |
||||
} |
||||
|
||||
.grey-button { |
||||
background: #797979 !important; |
||||
} |
||||
|
||||
hr { |
||||
// display: block; |
||||
// height: 1px; |
||||
border: 0; |
||||
border-top: 1px solid #b8b8b8; |
||||
// margin: 1em 0; |
||||
// padding: 0; |
||||
} |
||||
body { |
||||
font-family: Helvetica; |
||||
background: #eee; |
||||
-webkit-font-smoothing: antialiased; |
||||
} |
||||
|
||||
.title { |
||||
text-align: center; |
||||
} |
||||
|
||||
h1, |
||||
h3 { |
||||
font-weight: 300; |
||||
} |
||||
|
||||
h1 { |
||||
color: #636363; |
||||
} |
||||
|
||||
ul { |
||||
list-style: none; |
||||
padding-left: 0; |
||||
} |
||||
|
||||
.scope_title { |
||||
margin-top: 0; |
||||
margin-bottom: 0; |
||||
padding-left: 5px; |
||||
} |
||||
|
||||
.scope_description { |
||||
margin-top: 0; |
||||
padding-left: 15px; |
||||
font-size: 13px; |
||||
color: #202020; |
||||
} |
||||
|
||||
.card { |
||||
max-width: 480px; |
||||
margin: 4em auto; |
||||
padding: 3em 2em 2em 2em; |
||||
background: #fafafa; |
||||
border: 1px solid #ebebeb; |
||||
box-shadow: rgba(0, 0, 0, 0.14902) 0px 1px 1px 0px, |
||||
rgba(0, 0, 0, 0.09804) 0px 1px 2px 0px; |
||||
} |
Loading…
Reference in new issue