Skip to content

Commit

Permalink
Merge pull request #7 from rezk2ll/wellknown
Browse files Browse the repository at this point in the history
added Wellknown route
  • Loading branch information
rezk2ll committed Jan 22, 2024
2 parents 0fb954f + 79b479d commit f81f8f1
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 63 deletions.
4 changes: 2 additions & 2 deletions src/lib/components/landing/AccessSelect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import Logo from '../logo/Logo.svelte';
</script>

<div class="w-full flex flex-col md:flex-row justify-end h-[100vh] lg:h-full">
<div class="w-full flex flex-col md:flex-row justify-end h-[100dvh] lg:h-full">
<div
class="bg-white md:shadow-xl md:rounded-3xl flex flex-col space-y-6 w-full xl:w-[504px] md:px-[60px] pb-6 h-full lg:h-fit"
class="bg-white md:shadow-xl md:rounded-3xl flex flex-col space-y-6 w-full xl:w-[504px] md:px-[60px] pb-20 h-[calc(100%+40px)] pt-6 lg:pt-0 lg:pb-6 lg:h-fit"
id="start"
>
<div class="lg:hidden flex h-6 w-full items-center justify-center">
Expand Down
8 changes: 8 additions & 0 deletions src/lib/utils/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,11 @@ export const getOath2RedirectUri = (challenge: string, redirectUri: string, clie
export const gotoOath2RedirectUrl = (url: string, challenge: string, clientId: string): void => {
goto(getOath2RedirectUri(challenge, url, clientId));
};

/**
* removes trailing slash from a url
*
* @returns {string} the url without a trailing slash
*/
export const removeTrailingSlash = (url: string): string =>
url.endsWith('/') ? url.slice(0, -1) : url;
146 changes: 86 additions & 60 deletions src/routes/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const load: PageServerLoad = async ({ locals, url, cookies }) => {
const { session } = locals;
const redirectUrl = url.searchParams.get('post_registered_redirect_url') ?? undefined;
const postLoginUrl = url.searchParams.get('post_login_redirect_url') ?? undefined;
const challenge = url.searchParams.get('challenge_code') ?? undefined;
const clientId = url.searchParams.get('client_id') ?? undefined;

const cookie = cookies.get(authService.cookieName);
Expand All @@ -29,11 +30,18 @@ export const load: PageServerLoad = async ({ locals, url, cookies }) => {
...data,
redirectUrl,
postLoginUrl,
challenge,
clientId
}));

if (session.data.authenticated === true && cookie) {
throw redirect(302, postLoginUrl ?? '/success');
const destinationUrl = postLoginUrl
? challenge && clientId
? getOath2RedirectUri(challenge, postLoginUrl, clientId)
: getOidcRedirectUrl(postLoginUrl)
: '/success';

throw redirect(302, destinationUrl);
}

return {
Expand All @@ -43,91 +51,109 @@ export const load: PageServerLoad = async ({ locals, url, cookies }) => {

export const actions: Actions = {
sendOtp: async ({ request, locals }) => {
const data = await request.formData();
const phone = data.get('phone') as string;
try {
const data = await request.formData();
const phone = data.get('phone') as string;

if (!(await checkPhoneAvailability(phone))) {
return fail(400, { phone, phone_taken: true });
}
if (!(await checkPhoneAvailability(phone))) {
return fail(400, { phone, phone_taken: true });
}

if (!phone) {
return fail(400, { phone, missing: true });
}
if (!phone) {
return fail(400, { phone, missing: true });
}

if (!isPhoneValid(phone)) {
return fail(400, { phone, invalid: true });
}
if (!isPhoneValid(phone)) {
return fail(400, { phone, invalid: true });
}

const { last_sent } = locals.session.data;
const { last_sent } = locals.session.data;

if (last_sent && last_sent > Date.now() - 60000) {
return fail(400, { phone, invalid: true });
}
if (last_sent && last_sent > Date.now() - 60000) {
return fail(400, { phone, invalid: true });
}

const token = await send(phone);
const token = await send(phone);

await locals.session.set({
otp_request_token: token,
last_sent: Date.now(),
phone,
verified: false,
authenticated: false
});
await locals.session.set({
otp_request_token: token,
last_sent: Date.now(),
phone,
verified: false,
authenticated: false
});

return { sent: true };
return { sent: true };
} catch (error) {
return fail(400, { send_failed: true });
}
},

checkOtp: async ({ request, locals }) => {
const data = await request.formData();
const password = data.get('password') as string;
const { session } = locals;

if (!session.data.phone) {
return fail(400, { missing: true });
}

if (!password || !session.data.otp_request_token) {
return fail(400, { incorrect: true });
}

const verification = await verify(session.data.phone, password, session.data.otp_request_token);

if (verification === 'correct') {
await locals.session.update((data) => ({
...data,
verified: true
}));
try {
const data = await request.formData();
const password = data.get('password') as string;
const { session } = locals;

return { verified: true };
} else if (verification === 'timeout') {
await locals.session.update((data) => ({
...data,
verified: false
}));
if (!session.data.phone) {
return fail(400, { missing: true });
}

return fail(400, { timeout: true });
} else {
await locals.session.update((data) => ({
...data,
verified: false
}));
if (!password || !session.data.otp_request_token) {
return fail(400, { incorrect: true });
}

return fail(400, { incorrect: true });
const verification = await verify(
session.data.phone,
password,
session.data.otp_request_token
);

if (verification === 'correct') {
await locals.session.update((data) => ({
...data,
verified: true
}));

return { verified: true };
} else if (verification === 'timeout') {
await locals.session.update((data) => ({
...data,
verified: false
}));

return fail(400, { timeout: true });
} else {
await locals.session.update((data) => ({
...data,
verified: false
}));

return fail(400, { incorrect: true });
}
} catch (error) {
console.log('failed');
return fail(400, { check_failed: true });
}
},

register: async ({ request, locals, cookies, url }) => {
try {
const data = await request.formData();
const { session } = locals;
const phone = data.get('phone') as string;
const { phone: verifiedPhone, redirectUrl = null, challenge = null, clientId = null } = session.data;
const {
phone: verifiedPhone,
redirectUrl = null,
challenge = null,
clientId = null,
verified
} = locals.session.data;

if (!phone || isPhoneValid(phone) === false || !(await checkPhoneAvailability(phone))) {
return fail(400, { invalid_phone: true });
}

if (!session.data.verified || verifiedPhone !== phone) {
if (!verified || verifiedPhone !== phone) {
return fail(400, { invalid_phone: true });
}

Expand Down
92 changes: 92 additions & 0 deletions src/routes/[x+2e]well-known/openid-configuration/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { type RequestHandler, json } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import { getUrl, removeTrailingSlash } from '$lib/utils/url';

export const GET: RequestHandler = async () => {
const authServer = getUrl(env.AUTH_URL);

return json({
backchannel_logout_session_supported: true,
introspection_endpoint_auth_methods_supported: ['client_secret_post', 'client_secret_basic'],
response_modes_supported: ['query', 'fragment', 'form_post'],
jwks_uri: `${authServer}oauth2/jwks`,
end_session_endpoint: `${authServer}oauth2/logout`,
grant_types_supported: ['authorization_code', 'refresh_token'],
authorization_endpoint: `${authServer}oauth2/authorize`,
response_types_supported: ['code'],
backchannel_logout_supported: true,
frontchannel_logout_session_supported: true,
userinfo_encryption_enc_values_supported: [
'A256CBC-HS512',
'A256GCM',
'A192CBC-HS384',
'A192GCM',
'A128CBC-HS256',
'A128GCM'
],
frontchannel_logout_supported: true,
request_uri_parameter_supported: true,
acr_values_supported: ['loa-4', 'loa-1', 'loa-2', 'loa-5', 'loa-3'],
id_token_signing_alg_values_supported: [
'none',
'HS256',
'HS384',
'HS512',
'RS256',
'RS384',
'RS512',
'PS256',
'PS384',
'PS512'
],
request_parameter_supported: true,
token_endpoint: `${authServer}oauth2/token`,
userinfo_endpoint: `${authServer}oauth2/userinfo`,
issuer: removeTrailingSlash(authServer),
claims_supported: ['sub', 'iss', 'auth_time', 'acr', 'sid'],
subject_types_supported: ['public'],
scopes_supported: ['openid', 'profile', 'email', 'address', 'phone'],
id_token_encryption_enc_values_supported: [
'A256CBC-HS512',
'A256GCM',
'A192CBC-HS384',
'A192GCM',
'A128CBC-HS256',
'A128GCM'
],
require_request_uri_registration: true,
id_token_encryption_alg_values_supported: [
'RSA-OAEP',
'ECDH-ES',
'RSA-OAEP-256',
'ECDH-ES+A256KW',
'ECDH-ES+A192KW',
'ECDH-ES+A128KW',
'RSA1_5'
],
token_endpoint_auth_methods_supported: ['client_secret_post', 'client_secret_basic'],
userinfo_encryption_alg_values_supported: [
'RSA-OAEP',
'ECDH-ES',
'RSA-OAEP-256',
'ECDH-ES+A256KW',
'ECDH-ES+A192KW',
'ECDH-ES+A128KW',
'RSA1_5'
],
code_challenge_methods_supported: ['plain', 'S256'],
introspection_endpoint: `${authServer}oauth2/introspect`,
userinfo_signing_alg_values_supported: [
'none',
'HS256',
'HS384',
'HS512',
'RS256',
'RS384',
'RS512',
'PS256',
'PS384',
'PS512'
]
});
};
2 changes: 1 addition & 1 deletion src/routes/success/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ export const load: PageServerLoad = async ({ parent, cookies }) => {
phone: session.phone,
redirectUrl: session.redirectUrl ?? null,
challenge: session.challenge ?? null,
clientId: session.clientId ?? null,
clientId: session.clientId ?? null
};
};

0 comments on commit f81f8f1

Please sign in to comment.