workin on idc login flow

This commit is contained in:
2025-07-03 13:02:31 +02:00
parent 38081894ef
commit b9bff9733d
11 changed files with 234 additions and 97 deletions

View File

@@ -32,7 +32,7 @@
<Menu />
<Route path="/user" component={User} />
<Route path="/user/:user_id/edit" component={UserEdit} />
<Route path="/user/service/:serviceName" component={EditService} />
<Route path="/user/oidc/:serviceName" component={EditService} />
<Route>
<p>Page not found</p>
</Route>

View File

@@ -4,6 +4,7 @@
import { checkUser, tryLogin } from '../user.svelte.js';
let credentials = { username : null, password : null }
let services = $state([]);
function doLogin(ev){
tryLogin(credentials);
@@ -15,7 +16,26 @@
onMount(async () => {
await checkUser();
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/oidc/buttons`;
const resp = await fetch(url,{credentials:'include'});
if (resp.ok){
const json = await resp.json();
for (let service of json) services.push(service);
}
});
async function redirectTo(service){
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/oidc/redirect/${service}`;
const resp = await fetch(url,{credentials:'include'});
if (resp.ok){
var json = await resp.json();
if (json.authorization_endpoint) {
var endpoint = json.authorization_endpoint;
delete json.authorization_endpoint;
location.href = endpoint + '?' + new URLSearchParams(json);
}
}
}
</script>
<style>
@@ -47,6 +67,7 @@
</form>
<fieldset>
<legend>{t('login.OIDC_Login')}</legend>
<button>SRSoftware</button>
<button>ORC ID</button>
{#each services as service,i}
<button on:click={() => redirectTo(service)}>{service}</button>
{/each}
</fieldset>

View File

@@ -0,0 +1,46 @@
<script>
import { t } from '../../translations.svelte.js';
import { user } from '../../user.svelte.js';
import { onMount } from 'svelte';
let connections = $state([]);
onMount(async () => {
let url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/oidc/connected`;
let resp = await fetch(url,{credentials:'include'});
if (resp.ok){
const arr = await resp.json();
for (let entry of arr){
connections.push(entry)
console.log(entry);
}
}
});
</script>
{#if connections.length>0}
<fieldset tabindex="0">
<legend>{t('user.connected_services')}</legend>
<table>
<thead>
<tr>
<th>{t('user.service')}</th>
<th>{t('user.foreign_id')}</th>
<th>{t('user.actions')}</th>
</tr>
</thead>
<tbody>
{#each connections as connection,i}
<tr>
<td>{connection.service}</td>
<td>{connection.foreign_id}</td>
<td>
<button>{t('user.unlink')}</button>
</td>
</tr>
{/each}
</tbody>
</table>
</fieldset>
{/if}

View File

@@ -9,7 +9,7 @@
let services = $state([]);
onMount(async () => {
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/service/buttons`;
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/oidc/buttons`;
const resp = await fetch(url,{credentials:'include'});
if (resp.ok){
const json = await resp.json();
@@ -20,7 +20,10 @@
</script>
<fieldset tabindex="0">
<legend>{t('user.login_services')} <button>{t('user.add_login_service')}</button></legend>
<legend>
{t('user.login_services')}
<button>{t('user.add_login_service')}</button>
</legend>
<table>
<thead>
<tr>
@@ -35,7 +38,7 @@
<td>
<button>{t('user.connect_service')}</button>
{#if user.permissions.includes('MANAGE_LOGIN_SERVICES')}
<button onclick={() => router.navigate(`/user/service/${service}`)}>{t('user.edit')}</button>
<button onclick={() => router.navigate(`/user/oidc/${service}`)}>{t('user.edit')}</button>
<button>{t('user.delete')}</button>
{/if}
</td>

View File

@@ -0,0 +1,65 @@
<script>
import { t } from '../../translations.svelte.js';
import { user } from '../../user.svelte.js';
import { useTinyRouter } from 'svelte-tiny-router';
import EditPassword from './EditPassword.svelte';
const router = useTinyRouter();
let editPassword = false;
</script>
<fieldset>
<legend>
{t('user.your_profile')} <button onclick={() => router.navigate(`/user/${user.id}/edit`)}>{t('user.edit')}</button>
</legend>
<table>
<tbody>
<tr>
<th>{t('user.id')}</th>
<td>{user.id}</td>
</tr>
<tr>
<th>{t('user.name')}</th>
<td>{user.name}</td>
</tr>
<tr>
<th>{t('user.login')}</th>
<td>{user.login}</td>
</tr>
<tr>
<th>{t('user.email')}</th>
<td>{user.email}</td>
</tr>
<tr>
<th>{t('user.language')}</th>
<td>{user.language}</td>
</tr>
<tr>
<th>{t('user.theme')}</th>
<td>{user.theme}</td>
</tr>
<tr>
<th>{t('user.password')}</th>
<td>
{#if editPassword}
<EditPassword bind:editPassword={editPassword} />
{:else}
<button onclick={() => editPassword = true}>{t('user.edit_password')}</button>
{/if}
</td>
</tr>
<tr>
<th>{t('user.permissions')}</th>
<td>
<ul>
{#each user.permissions as permission,i}
<li>{t('user.'+permission)}</li>
{/each}
</ul>
</td>
</tr>
</tbody>
</table>
</fieldset>

View File

@@ -1,92 +1,17 @@
<script>
import { t } from '../../translations.svelte.js';
import { user } from '../../user.svelte.js';
import { useTinyRouter } from 'svelte-tiny-router';
import EditPassword from './EditPassword.svelte';
import UserList from './List.svelte';
import Services from './ConnectedServices.svelte';
import LoginServiceList from './LoginServices.svelte';
const router = useTinyRouter();
let editPassword = false;
async function patch(changeset){
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/${user.id}`;
const response = await fetch(url,{
method: 'PATCH',
credentials: 'include',
body: JSON.stringify(changeset)
});
if (response.ok) {
const json = await response.json();
for (let key of Object.keys(json)) user[key] = json[key];
}
}
async function fetchThemes(){
const url = `${location.protocol}//${location.host.replace('5173','8080')}/themes.json`;
return fetch(url);
}
import Profile from './Profile.svelte';
import UserList from './List.svelte';
</script>
<h1>{t('user.user_module')}</h1>
<fieldset>
<legend>
{t('user.your_profile')} <button onclick={() => router.navigate(`/user/${user.id}/edit`)}>{t('user.edit')}</button>
</legend>
<table>
<tbody>
<tr>
<th>{t('user.id')}</th>
<td>{user.id}</td>
</tr>
<tr>
<th>{t('user.name')}</th>
<td>{user.name}</td>
</tr>
<tr>
<th>{t('user.login')}</th>
<td>{user.login}</td>
</tr>
<tr>
<th>{t('user.email')}</th>
<td>{user.email}</td>
</tr>
<tr>
<th>{t('user.language')}</th>
<td>{user.language}</td>
</tr>
<tr>
<th>{t('user.theme')}</th>
<td>{user.theme}</td>
</tr>
<tr>
<th>{t('user.password')}</th>
<td>
{#if editPassword}
<EditPassword bind:editPassword={editPassword} />
{:else}
<button onclick={() => editPassword = true}>{t('user.edit_password')}</button>
{/if}
</td>
</tr>
<tr>
<th>{t('user.permissions')}</th>
<td>
<ul>
{#each user.permissions as permission,i}
<li>{t('user.'+permission)}</li>
{/each}
</ul>
</td>
</tr>
</tbody>
</table>
</fieldset>
<Profile />
<Services />
{#if user.permissions.includes('LIST_USERS')}
<UserList />