This commit is contained in:
Evert Prants 2025-03-08 10:04:52 +02:00
parent 82fe88189d
commit 15e02f978c
Signed by: evert
GPG Key ID: 0960A17F9F40237D
8 changed files with 68 additions and 10 deletions

View File

@ -73,3 +73,8 @@ a[target='_blank']::after {
position: absolute;
}
}
ul {
padding-left: 1.45rem;
margin: 0;
}

View File

@ -37,7 +37,6 @@
height: 120px;
width: 120px;
flex: 0 0 120px;
background-color: var(--in-normalized-background);
&.small {
height: 60px;

View File

@ -0,0 +1,26 @@
<script lang="ts">
interface Props {
children?: import('svelte').Snippet;
padded?: boolean;
}
let { children, padded }: Props = $props();
</script>
<div class="form-actions{padded ? ' padded' : ''}">
{@render children?.()}
</div>
<style>
.form-actions {
display: flex;
gap: 16px;
width: 100%;
align-items: center;
justify-content: flex-end;
&.padded {
padding-right: 24px;
}
}
</style>

View File

@ -20,6 +20,7 @@ import { UserTokens, Users } from '$lib/server/users';
import type { OAuth2ClientInfo, PaginationMeta } from '$lib/types';
import { and, count, eq, like, or, sql } from 'drizzle-orm';
import { createLocalJWKSet, exportJWK, importJWK, jwtVerify, type JWK } from 'jose';
import { ensureArray } from '$lib/utils';
export enum OAuth2ClientURLType {
REDIRECT_URI = 'redirect_uri',
@ -203,7 +204,15 @@ export class OAuth2Clients {
return scope;
}
return scope.includes(',') ? scope.split(',').map((item) => item.trim()) : scope.split(' ');
const delimeterSplit = scope.includes(',') ? scope.split(',') : scope.split(' ');
return delimeterSplit.reduce<string[]>((list, scope) => {
const trimmed = scope.trim();
if (!!trimmed) {
list.push(trimmed);
}
return list;
}, []);
}
static joinScope(scope: string[]): string {
@ -549,7 +558,7 @@ export class OAuth2Clients {
});
// Check audience, token must be intended for our service
const checkAudience = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
const checkAudience = ensureArray(payload.aud);
if (
!checkAudience.some(
(entry) => entry?.startsWith(env.PUBLIC_URL) || entry?.startsWith(privateEnv.JWT_ISSUER)

View File

@ -168,7 +168,7 @@ export class OAuth2Codes {
const user = await Users.getById(userId);
const accessToken = CryptoUtils.generateString(64);
const scopes = (!Array.isArray(scope) ? OAuth2Clients.splitScope(scope) : scope).join(' ');
const scopes = OAuth2Clients.joinScope(OAuth2Clients.splitScope(scope));
const expiresAt = new Date(Date.now() + ttl * 1000);
const pcke =
@ -238,7 +238,7 @@ export class OAuth2AccessTokens {
const user = userId != null ? await Users.getById(userId) : undefined;
const accessToken = CryptoUtils.generateString(128);
const scopes = (!Array.isArray(scope) ? OAuth2Clients.splitScope(scope) : scope).join(' ');
const scopes = OAuth2Clients.joinScope(OAuth2Clients.splitScope(scope));
const expiresAt = new Date(Date.now() + ttl * 1000);
@ -298,7 +298,7 @@ export class OAuth2RefreshTokens {
const user = await Users.getById(userId);
const accessToken = CryptoUtils.generateString(64);
const scopes = (!Array.isArray(scope) ? OAuth2Clients.splitScope(scope) : scope).join(' ');
const scopes = OAuth2Clients.joinScope(OAuth2Clients.splitScope(scope));
const expiresAt = new Date(Date.now() + OAuth2Tokens.refreshTtl * 1000);
@ -350,7 +350,7 @@ export class OAuth2DeviceCodes {
const userCode =
`${CryptoUtils.generateString(3)}-${CryptoUtils.generateString(3)}`.toUpperCase();
const scopes = (!Array.isArray(scope) ? OAuth2Clients.splitScope(scope) : scope).join(' ');
const scopes = OAuth2Clients.joinScope(OAuth2Clients.splitScope(scope));
const expiresAt = new Date(Date.now() + OAuth2Tokens.deviceTtl * 1000);
await OAuth2Tokens.insert(
@ -442,7 +442,7 @@ export class OAuth2ParCodes {
const client = await OAuth2Clients.fetchById(clientId);
const parCode = CryptoUtils.generateString(32);
const scopes = (!Array.isArray(scope) ? OAuth2Clients.splitScope(scope) : scope).join(' ');
const scopes = OAuth2Clients.joinScope(OAuth2Clients.splitScope(scope));
const expiresAt = new Date(Date.now() + OAuth2Tokens.parTtl * 1000);
const pcke =

View File

@ -14,6 +14,12 @@ export const hasPrivileges = (list: string[], privileges: RequiredPrivileges) =>
return list.includes(item);
});
/**
* Wait until the `check` function returns a truthy value.
* @param check Condition to run
* @param checkInterval Interval to run condition (ms)
* @param checkTimeout Timeout of the check (ms)
*/
export const waitIsTruthy = (check: () => boolean, checkInterval = 500, checkTimeout = 5000) => {
let time = 0;
return new Promise<void>((resolve, reject) => {
@ -46,3 +52,10 @@ export function self<TFn extends (event: Event, ...args: Array<unknown>) => void
}
};
}
/**
* Ensures that the given input is an array.
* @param input Array or single value
* @returns Array
*/
export const ensureArray = <T>(input: T | T[]): T[] => (Array.isArray(input) ? input : [input]);

View File

@ -9,6 +9,7 @@
import SplitView from '$lib/components/container/SplitView.svelte';
import Button from '$lib/components/Button.svelte';
import AdminAuditCard from '$lib/components/admin/AdminAuditCard.svelte';
import FormActions from '$lib/components/form/FormActions.svelte';
interface Props {
data: PageData;
@ -70,9 +71,10 @@
/>
</FormControl>
<div>
<FormActions padded>
<a href="/ssoadmin/audit">{$t('common.clear')}</a>
<Button type="submit">{$t('common.filter')}</Button>
</div>
</FormActions>
</ColumnView>
</form>

View File

@ -16,6 +16,10 @@ const config = {
// This is reimplemented in hooks.server.ts to allow certain endpoints
csrf: {
checkOrigin: false
},
router: {
resolution: 'server'
}
}
};