Browse Source

Merge commit 'eec87f678da8a48051f809a8788f5d462ed66a0e' into sqlite

sqlite
Stephan Richter 9 months ago
parent
commit
c03c491fe7
  1. 2
      build.gradle
  2. 1
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java
  3. 48
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/data/Client.java
  4. 5
      de.srsoftware.oidc.api/src/test/java/de/srsoftware/oidc/api/ClientServiceTest.java
  5. 5
      de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java
  6. 2
      de.srsoftware.oidc.backend/build.gradle
  7. 39
      de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java
  8. 5
      de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/TokenController.java
  9. 4
      de.srsoftware.oidc.datastore.encrypted/src/main/java/de/srsoftware/oidc/datastore/encrypted/EncryptedClientService.java
  10. 4
      de.srsoftware.oidc.datastore.encrypted/src/main/java/de/srsoftware/oidc/datastore/encrypted/EncryptedUserService.java
  11. 2
      de.srsoftware.oidc.datastore.file/src/main/java/de/srsoftware/oidc/datastore/file/FileStore.java
  12. 8
      de.srsoftware.oidc.web/src/main/resources/de/edit_client.html
  13. 9
      de.srsoftware.oidc.web/src/main/resources/en/edit_client.html
  14. 5
      de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js
  15. 22
      de.srsoftware.oidc.web/src/main/resources/en/scripts/edit_client.js
  16. 4
      de.srsoftware.oidc.web/src/main/resources/en/style.css
  17. 1
      de.srsoftware.oidc.web/src/main/resources/en/todo.html

2
build.gradle

@ -5,7 +5,7 @@ plugins {
group = 'de.srsoftware' group = 'de.srsoftware'
version = '1.0-SNAPSHOT' version = '1.0.1'
jar.enabled = false jar.enabled = false
build.enabled = false build.enabled = false

1
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java

@ -64,6 +64,7 @@ public class Constants {
public static final String START_TLS = "start_tls"; public static final String START_TLS = "start_tls";
public static final String TOKEN = "token"; public static final String TOKEN = "token";
public static final String TOKEN_TYPE = "token_type"; public static final String TOKEN_TYPE = "token_type";
public static final String TOKEN_VALIDITY = "token_validity";
public static final String TRUST = "trust"; public static final String TRUST = "trust";
public static final String UNAUTHORIZED_CLIENT = "unauthorized_client"; public static final String UNAUTHORIZED_CLIENT = "unauthorized_client";
public static final String USER = "user"; public static final String USER = "user";

48
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/data/Client.java

@ -5,6 +5,7 @@ package de.srsoftware.oidc.api.data;
import static de.srsoftware.oidc.api.Constants.*; import static de.srsoftware.oidc.api.Constants.*;
import static de.srsoftware.utils.Optionals.nullable; import static de.srsoftware.utils.Optionals.nullable;
import java.time.Duration;
import java.util.*; import java.util.*;
public final class Client { public final class Client {
@ -14,15 +15,36 @@ public final class Client {
private final String name; private final String name;
private final String secret; private final String secret;
private final Set<String> redirectUris; private final Set<String> redirectUris;
private Duration tokenValidity;
public Client(String id, String name, String secret, Set<String> redirectUris) { public Client(String id, String name, String secret, Set<String> redirectUris) {
this.id = id; this.id = id;
landingPage = null; landingPage = null;
this.name = name; this.name = name;
this.secret = secret; this.secret = secret;
this.redirectUris = redirectUris; this.redirectUris = redirectUris;
this.tokenValidity = Duration.ofMinutes(10);
} }
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (Client)obj;
return Objects.equals(this.id, that.id) //
&& Objects.equals(this.name, that.name) //
&& Objects.equals(this.secret, that.secret) //
&& Objects.equals(this.redirectUris, that.redirectUris) //
&& Objects.equals(landingPage, that.landingPage) //
&& Objects.equals(tokenValidity, that.tokenValidity);
}
@Override
public int hashCode() {
return Objects.hash(id, name, secret, redirectUris);
}
public String id() { public String id() {
return id; return id;
} }
@ -53,6 +75,7 @@ public final class Client {
map.put(NAME, name); map.put(NAME, name);
nullable(redirectUris).ifPresent(uris -> map.put(REDIRECT_URIS, uris)); nullable(redirectUris).ifPresent(uris -> map.put(REDIRECT_URIS, uris));
nullable(landingPage).ifPresent(lp -> map.put(LANDING_PAGE, lp)); nullable(landingPage).ifPresent(lp -> map.put(LANDING_PAGE, lp));
nullable(tokenValidity).ifPresent(tv -> map.put(TOKEN_VALIDITY, tv.toMinutes()));
return map; return map;
} }
@ -65,17 +88,14 @@ public final class Client {
return redirectUris; return redirectUris;
} }
@Override
public boolean equals(Object obj) { public Duration tokenValidity() {
if (obj == this) return true; return tokenValidity;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (Client)obj;
return Objects.equals(this.id, that.id) && Objects.equals(this.name, that.name) && Objects.equals(this.secret, that.secret) && Objects.equals(this.redirectUris, that.redirectUris);
} }
@Override public Client tokenValidity(Duration newValue) {
public int hashCode() { this.tokenValidity = newValue;
return Objects.hash(id, name, secret, redirectUris); return this;
} }
@Override @Override

5
de.srsoftware.oidc.api/src/test/java/de/srsoftware/oidc/api/ClientServiceTest.java

@ -6,6 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import de.srsoftware.oidc.api.data.Client; import de.srsoftware.oidc.api.data.Client;
import java.time.Duration;
import java.util.Set; import java.util.Set;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -23,7 +24,7 @@ public abstract class ClientServiceTest {
var clientId = uuid(); var clientId = uuid();
var clientSecret = uuid(); var clientSecret = uuid();
var landingPage = uuid(); var landingPage = uuid();
var client = new Client(clientId, NAME, clientSecret, Set.of(URI)).landingPage(landingPage); var client = new Client(clientId, NAME, clientSecret, Set.of(URI));
var list = cs.save(client).listClients(); var list = cs.save(client).listClients();
assertEquals(1, list.size()); assertEquals(1, list.size());
assertTrue(list.contains(client)); assertTrue(list.contains(client));
@ -37,7 +38,7 @@ public abstract class ClientServiceTest {
var clientId = uuid(); var clientId = uuid();
var clientSecret = uuid(); var clientSecret = uuid();
var landingPage = uuid(); var landingPage = uuid();
var client = new Client(clientId, NAME, clientSecret, Set.of(URI)).landingPage(landingPage); var client = new Client(clientId, NAME, clientSecret, Set.of(URI)).landingPage(landingPage).tokenValidity(Duration.ofMinutes(23));
var optClient = cs.save(client).getClient(clientId); var optClient = cs.save(client).getClient(clientId);
assertTrue(optClient.isPresent()); assertTrue(optClient.isPresent());
assertEquals(client, optClient.get()); assertEquals(client, optClient.get());

5
de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java

@ -82,8 +82,9 @@ public class Application {
new WellKnownController().bindPath(WELL_KNOWN, "/realms/oidc" + WELL_KNOWN).on(server); new WellKnownController().bindPath(WELL_KNOWN, "/realms/oidc" + WELL_KNOWN).on(server);
new UserController(mailConfig, sessionService, userService, staticPages).bindPath(API_USER).on(server); new UserController(mailConfig, sessionService, userService, staticPages).bindPath(API_USER).on(server);
var tokenControllerConfig = new TokenController.Configuration(10); var tokenControllerConfig = new TokenController.Configuration(10);
new TokenController(authService, clientService, keyManager, userService, tokenControllerConfig).bindPath(API_TOKEN).on(server); var tokenController = new TokenController(authService, clientService, keyManager, userService, tokenControllerConfig);
new ClientController(authService, clientService, sessionService, userService).bindPath(API_CLIENT).on(server); tokenController.bindPath(API_TOKEN).on(server);
new ClientController(authService, clientService, sessionService, userService, tokenController).bindPath(API_CLIENT).on(server);
new KeyStoreController(keyStore).bindPath(JWKS).on(server); new KeyStoreController(keyStore).bindPath(JWKS).on(server);
new EmailController(mailConfig, sessionService, userService).bindPath(API_EMAIL).on(server); new EmailController(mailConfig, sessionService, userService).bindPath(API_EMAIL).on(server);
server.setExecutor(Executors.newCachedThreadPool()); server.setExecutor(Executors.newCachedThreadPool());

2
de.srsoftware.oidc.backend/build.gradle

@ -24,4 +24,4 @@ dependencies {
test { test {
useJUnitPlatform() useJUnitPlatform()
} }

39
de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java

@ -14,6 +14,7 @@ import de.srsoftware.oidc.api.data.User;
import de.srsoftware.utils.Error; import de.srsoftware.utils.Error;
import de.srsoftware.utils.Optionals; import de.srsoftware.utils.Optionals;
import java.io.IOException; import java.io.IOException;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
@ -24,12 +25,14 @@ public class ClientController extends Controller {
private final AuthorizationService authorizations; private final AuthorizationService authorizations;
private final ClientService clients; private final ClientService clients;
private final UserService users; private final UserService users;
private final TokenController tokens;
public ClientController(AuthorizationService authorizationService, ClientService clientService, SessionService sessionService, UserService userService) { public ClientController(AuthorizationService authorizationService, ClientService clientService, SessionService sessionService, UserService userService, TokenController tokenController) {
super(sessionService); super(sessionService);
authorizations = authorizationService; authorizations = authorizationService;
clients = clientService; clients = clientService;
users = userService; users = userService;
tokens = tokenController;
} }
@ -49,15 +52,18 @@ public class ClientController extends Controller {
var scopes = toList(json, SCOPE); var scopes = toList(json, SCOPE);
if (!scopes.contains(OPENID)) return badRequest(ex, Error.message(ERROR_MISSING_PARAMETER, PARAM, "Scope: openid", STATE, state)); if (!scopes.contains(OPENID)) return badRequest(ex, Error.message(ERROR_MISSING_PARAMETER, PARAM, "Scope: openid", STATE, state));
var responseTypes = toList(json, RESPONSE_TYPE); var responseTypes = toList(json, RESPONSE_TYPE);
var types = 0;
for (var responseType : responseTypes) { for (var responseType : responseTypes) {
switch (responseType) { switch (responseType) {
case CODE: case CODE:
case ID_TOKEN:
types++;
break; break;
default: default:
return badRequest(ex, Error.message(ERROR_UNSUPPORTED_RESPONSE_TYPE, RESPONSE_TYPE, responseType, STATE, state)); return badRequest(ex, Error.message(ERROR_UNSUPPORTED_RESPONSE_TYPE, RESPONSE_TYPE, responseType, STATE, state));
} }
} }
if (!responseTypes.contains(CODE)) return badRequest(ex, Error.message(ERROR_MISSING_CODE_RESPONSE_TYPE, STATE, state)); if (types < 1) return badRequest(ex, Error.message(ERROR_MISSING_CODE_RESPONSE_TYPE, STATE, state));
var client = optClient.get(); var client = optClient.get();
var redirect = json.getString(REDIRECT_URI); var redirect = json.getString(REDIRECT_URI);
@ -73,16 +79,32 @@ public class ClientController extends Controller {
} }
if (json.has(NONCE)) authorizations.nonce(user.uuid(), client.id(), json.getString(NONCE)); if (json.has(NONCE)) authorizations.nonce(user.uuid(), client.id(), json.getString(NONCE));
var authResult = authorizations.getAuthorization(user.uuid(), client.id(), scopes); var authResult = authorizations.getAuthorization(user.uuid(), client.id(), scopes);
if (!authResult.unauthorizedScopes().isEmpty()) { if (!authResult.unauthorizedScopes().isEmpty()) {
return sendContent(ex, Map.of("unauthorized_scopes", authResult.unauthorizedScopes(), "rp", client.name())); return sendContent(ex, Map.of("unauthorized_scopes", authResult.unauthorizedScopes(), "rp", client.name()));
} }
var joinedAuthorizedScopes = Optionals.nullable(authResult.authorizedScopes()).map(AuthorizedScopes::scopes).map(list -> String.join(" ", list)); var joinedAuthorizedScopes = Optionals.nullable(authResult.authorizedScopes()).map(AuthorizedScopes::scopes).map(list -> String.join(" ", list));
var result = new HashMap<String, String>();
var result = new HashMap<String, Object>();
joinedAuthorizedScopes.ifPresent(authorizedScopes -> result.put(SCOPE, authorizedScopes)); joinedAuthorizedScopes.ifPresent(authorizedScopes -> result.put(SCOPE, authorizedScopes));
result.put(CODE, authResult.authCode());
if (state != null) result.put(STATE, state); if (responseTypes.contains(ID_TOKEN)) {
var accessToken = users.accessToken(user);
var issuer = hostname(ex);
String jwToken = tokens.createJWT(client, user, accessToken, issuer);
ex.getResponseHeaders().add("Cache-Control", "no-store");
result.put(ACCESS_TOKEN, accessToken.id());
result.put(TOKEN_TYPE, BEARER);
result.put(EXPIRES_IN, 3600);
result.put(ID_TOKEN, jwToken);
} else if (responseTypes.contains(CODE)) {
result.put(CODE, authResult.authCode());
if (state != null) result.put(STATE, state);
}
return sendContent(ex, result); return sendContent(ex, result);
} }
@ -209,8 +231,9 @@ public class ClientController extends Controller {
for (Object o : json.getJSONArray(REDIRECT_URIS)) { for (Object o : json.getJSONArray(REDIRECT_URIS)) {
if (o instanceof String s) redirects.add(s); if (o instanceof String s) redirects.add(s);
} }
var landingPage = json.has(LANDING_PAGE) ? json.getString(LANDING_PAGE) : null; var landingPage = json.has(LANDING_PAGE) ? json.getString(LANDING_PAGE) : null;
var client = new Client(json.getString(CLIENT_ID), json.getString(NAME), json.getString(SECRET), redirects).landingPage(landingPage); var token_duration = Duration.ofMinutes(json.has(TOKEN_VALIDITY) ? json.getLong(TOKEN_VALIDITY) : 10);
var client = new Client(json.getString(CLIENT_ID), json.getString(NAME), json.getString(SECRET), redirects).landingPage(landingPage).tokenValidity(token_duration);
clients.save(client); clients.save(client);
return sendContent(ex, client); return sendContent(ex, client);
} }

5
de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/TokenController.java

@ -127,7 +127,7 @@ public class TokenController extends PathHandler {
return sendContent(ex, response); return sendContent(ex, response);
} }
private String createJWT(Client client, User user, AccessToken accessToken, String issuer) { String createJWT(Client client, User user, AccessToken accessToken, String issuer) {
try { try {
PublicJsonWebKey key = keyManager.getKey(); PublicJsonWebKey key = keyManager.getKey();
var algo = key.getAlgorithm(); var algo = key.getAlgorithm();
@ -176,11 +176,12 @@ public class TokenController extends PathHandler {
claims.setIssuer(issuer); // who creates the token and signs it claims.setIssuer(issuer); // who creates the token and signs it
claims.setSubject(user.uuid()); // the subject/principal is whom the token is about claims.setSubject(user.uuid()); // the subject/principal is whom the token is about
claims.setAudience(client.id()); claims.setAudience(client.id());
claims.setExpirationTimeMinutesInTheFuture(config.tokenExpirationMinutes); // time when the token will expire (10 minutes from now) claims.setExpirationTimeMinutesInTheFuture(client.tokenValidity().toMinutes()); // time when the token will expire (10 minutes from now)
claims.setIssuedAtToNow(); claims.setIssuedAtToNow();
claims.setClaim(AT_HASH, atHash); claims.setClaim(AT_HASH, atHash);
claims.setClaim(CLIENT_ID, client.id()); claims.setClaim(CLIENT_ID, client.id());
claims.setClaim(EMAIL, user.email()); // additional claims/attributes about the subject can be added claims.setClaim(EMAIL, user.email()); // additional claims/attributes about the subject can be added
claims.setClaim(USER, user.username());
optNonce.ifPresent(nonce -> claims.setClaim(NONCE, nonce)); optNonce.ifPresent(nonce -> claims.setClaim(NONCE, nonce));
claims.setGeneratedJwtId(); // a unique identifier for the token claims.setGeneratedJwtId(); // a unique identifier for the token

4
de.srsoftware.oidc.datastore.encrypted/src/main/java/de/srsoftware/oidc/datastore/encrypted/EncryptedClientService.java

@ -19,12 +19,12 @@ public class EncryptedClientService extends EncryptedConfig implements ClientSer
public Client decrypt(Client client) { public Client decrypt(Client client) {
var decryptedUrls = client.redirectUris().stream().map(this::decrypt).collect(Collectors.toSet()); var decryptedUrls = client.redirectUris().stream().map(this::decrypt).collect(Collectors.toSet());
return new Client(decrypt(client.id()), decrypt(client.name()), decrypt(client.secret()), decryptedUrls).landingPage(decrypt(client.landingPage())); return new Client(decrypt(client.id()), decrypt(client.name()), decrypt(client.secret()), decryptedUrls).landingPage(decrypt(client.landingPage())).tokenValidity(client.tokenValidity());
} }
public Client encrypt(Client client) { public Client encrypt(Client client) {
var encryptedUrls = client.redirectUris().stream().map(this::encrypt).collect(Collectors.toSet()); var encryptedUrls = client.redirectUris().stream().map(this::encrypt).collect(Collectors.toSet());
return new Client(encrypt(client.id()), encrypt(client.name()), encrypt(client.secret()), encryptedUrls).landingPage(encrypt(client.landingPage())); return new Client(encrypt(client.id()), encrypt(client.name()), encrypt(client.secret()), encryptedUrls).landingPage(encrypt(client.landingPage())).tokenValidity(client.tokenValidity());
} }
@Override @Override

4
de.srsoftware.oidc.datastore.encrypted/src/main/java/de/srsoftware/oidc/datastore/encrypted/EncryptedUserService.java

@ -107,8 +107,8 @@ public class EncryptedUserService extends EncryptedConfig implements UserService
} }
for (var encryptedUser : backend.list()) { for (var encryptedUser : backend.list()) {
var decryptedUser = decrypt(encryptedUser); var decryptedUser = decrypt(encryptedUser);
if (!username.equals(decryptedUser.username())) continue; var match = List.of(decryptedUser.username(), decryptedUser.realName(), decryptedUser.email()).contains(username);
if (hasher.matches(password, decryptedUser.hashedPassword())) { if (match && hasher.matches(password, decryptedUser.hashedPassword())) {
this.unlock(username); this.unlock(username);
return Payload.of(decryptedUser); return Payload.of(decryptedUser);
} }

2
de.srsoftware.oidc.datastore.file/src/main/java/de/srsoftware/oidc/datastore/file/FileStore.java

@ -21,6 +21,7 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
@ -329,6 +330,7 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
} }
var client = new Client(clientId, clientData.getString(NAME), clientData.getString(SECRET), redirectUris); var client = new Client(clientId, clientData.getString(NAME), clientData.getString(SECRET), redirectUris);
if (clientData.has(LANDING_PAGE)) client.landingPage(clientData.getString(LANDING_PAGE)); if (clientData.has(LANDING_PAGE)) client.landingPage(clientData.getString(LANDING_PAGE));
if (clientData.has(TOKEN_VALIDITY)) client.tokenValidity(Duration.ofMinutes(clientData.getLong(TOKEN_VALIDITY)));
return client; return client;
} }

8
de.srsoftware.oidc.web/src/main/resources/de/edit_client.html

@ -37,6 +37,14 @@
<th>Ziel-Seite</th> <th>Ziel-Seite</th>
<td><input type="text" id="landing-page" /></td> <td><input type="text" id="landing-page" /></td>
</tr> </tr>
<tr>
<th>Gültigkeitsdauer von Access-Tokens</th>
<td>
<input type="range" id="token_validity" min="1" max="120" oninput="durationUpdate()" />
<br/>
<span id="days"></span> Tage, <span id="hours"></span> Stunden, <span id="minutes"></span> Minuten
</td>
</tr>
<tr> <tr>
<td></td> <td></td>
<td><button type="button" id="button" onclick="updateClient();">Aktualisieren</button></td> <td><button type="button" id="button" onclick="updateClient();">Aktualisieren</button></td>

9
de.srsoftware.oidc.web/src/main/resources/en/edit_client.html

@ -37,10 +37,19 @@
<th>Landing page</th> <th>Landing page</th>
<td><input type="text" id="landing-page" /></td> <td><input type="text" id="landing-page" /></td>
</tr> </tr>
<tr>
<th>Token validity duration</th>
<td>
<input type="range" id="token_validity" min="1" max="120" oninput="durationUpdate()" />
<br/>
<span id="days"></span> days, <span id="hours"></span> hours, <span id="minutes"></span> minutes
</td>
</tr>
<tr> <tr>
<td></td> <td></td>
<td><button type="button" id="button" onclick="updateClient();">Update</button></td> <td><button type="button" id="button" onclick="updateClient();">Update</button></td>
</tr> </tr>
</table> </table>
</fieldset> </fieldset>
<fieldset class="wide"> <fieldset class="wide">

5
de.srsoftware.oidc.web/src/main/resources/en/scripts/authorization.js

@ -35,8 +35,9 @@ function handleResponse(response){
return; return;
} }
if (json.scope){ if (json.scope){
var separator = json.id_token ? '#' : '?';
var query = Object.keys(json).map(key => `${key}=${encodeURIComponent(json[key])}`).join('&'); var query = Object.keys(json).map(key => `${key}=${encodeURIComponent(json[key])}`).join('&');
var url = params.get('redirect_uri') + '?' + query.toString(); var url = params.get('redirect_uri') + separator + query.toString();
redirect(url); redirect(url);
return; return;
} }
@ -53,7 +54,7 @@ function handleResponse(response){
if (json.error) show(json.error); if (json.error) show(json.error);
if (json.metadata.client_id) setText('client_id',json.metadata.client_id); if (json.metadata.client_id) setText('client_id',json.metadata.client_id);
if (json.metadata.parameter) setText('parameter',json.metadata.parameter); if (json.metadata.parameter) setText('parameter',json.metadata.parameter);
if (json.metadata.redirect_uri) setText('redirect_uri',json.metadata.redirect_uri); if (json.metadata.redirect_uri) setText('redirect_uri',json.metadata.redirect_uri);
if (json.metadata.response_type)setText('response_type',json.metadata.response_type) if (json.metadata.response_type)setText('response_type',json.metadata.response_type)
}); });
/*if (json.error != "invalid_request_uri"){ /*if (json.error != "invalid_request_uri"){

22
de.srsoftware.oidc.web/src/main/resources/en/scripts/edit_client.js

@ -1,5 +1,22 @@
var params = new URLSearchParams(window.location.search); var params = new URLSearchParams(window.location.search);
var id = params.get('id'); var id = params.get('id');
var token_validity = 10;
function displayDuration(){
var mins = token_validity;
hrs = Math.floor(mins/60);
mins-=60*hrs;
days = Math.floor(hrs/24);
hrs-=24*days;
setText('days',days);
setText('hours',hrs);
setText('minutes',mins);
}
function durationUpdate(){
token_validity = getValue('token_validity');
displayDuration();
}
function handleAutoDiscover(response){ function handleAutoDiscover(response){
if (response.ok){ if (response.ok){
@ -19,6 +36,8 @@ function handleLoadResponse(response){
get('client-secret').value = json.secret; get('client-secret').value = json.secret;
get('redirect-urls').value = json.redirect_uris.join("\n"); get('redirect-urls').value = json.redirect_uris.join("\n");
get('landing-page').value = json.landing_page?json.landing_page:''; get('landing-page').value = json.landing_page?json.landing_page:'';
token_validity = json.token_validity?json.token_validity:10;
displayDuration();
}); });
} }
} }
@ -44,7 +63,8 @@ function updateClient(){
name : getValue('client-name'), name : getValue('client-name'),
secret : getValue('client-secret'), secret : getValue('client-secret'),
redirect_uris : getValue('redirect-urls').split("\n"), redirect_uris : getValue('redirect-urls').split("\n"),
landing_page : getValue('landing-page') landing_page : getValue('landing-page'),
token_validity : getValue('token_validity')
}; };
fetch(client_controller+'/update',{ fetch(client_controller+'/update',{
method : 'POST', method : 'POST',

4
de.srsoftware.oidc.web/src/main/resources/en/style.css

@ -177,4 +177,8 @@ ul{
.permissions button:hover span{ .permissions button:hover span{
display: initial; display: initial;
}
nav{
margin-top: 5px;
} }

1
de.srsoftware.oidc.web/src/main/resources/en/todo.html

@ -16,6 +16,7 @@
<li>implement token refresh</li> <li>implement token refresh</li>
<li>Configuration im Frontend</li> <li>Configuration im Frontend</li>
<li>TOTP authentifizierung</li> <li>TOTP authentifizierung</li>
<li>Besserer Hinweis beim Zurücksetzen von Passworten, wenn das neue Passwort zu einfach ist</li>
</ul> </ul>
</div> </div>
</body> </body>

Loading…
Cancel
Save