Merge branch 'master' into ip-management
This commit is contained in:
commit
c5c85bf771
@ -73,3 +73,8 @@ a[target='_blank']::after {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 1.45rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
flex: 0 0 120px;
|
||||
background-color: var(--in-normalized-background);
|
||||
|
||||
&.small {
|
||||
height: 60px;
|
||||
|
26
src/lib/components/form/FormActions.svelte
Normal file
26
src/lib/components/form/FormActions.svelte
Normal 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>
|
@ -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)
|
||||
|
@ -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 =
|
||||
|
@ -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]);
|
||||
|
@ -9,8 +9,8 @@
|
||||
import SplitView from '$lib/components/container/SplitView.svelte';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import AdminAuditCard from '$lib/components/admin/AdminAuditCard.svelte';
|
||||
import { hasPrivileges } from '$lib/utils';
|
||||
import FormActions from '$lib/components/form/FormActions.svelte';
|
||||
import { hasPrivileges } from '$lib/utils';
|
||||
|
||||
interface Props {
|
||||
data: PageData;
|
||||
|
@ -16,6 +16,10 @@ const config = {
|
||||
// This is reimplemented in hooks.server.ts to allow certain endpoints
|
||||
csrf: {
|
||||
checkOrigin: false
|
||||
},
|
||||
|
||||
router: {
|
||||
resolution: 'server'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user