1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-08-05 05:05:17 +02:00

feat: Implement disable password authentication for users with social accounts

This commit is contained in:
Sean Morley 2025-03-16 21:49:00 -04:00
parent 189cd0ee69
commit a38828eb45
14 changed files with 184 additions and 17 deletions

View file

@ -16,6 +16,7 @@ declare global {
uuid: string;
public_profile: boolean;
has_password: boolean;
disable_password: boolean;
} | null;
locale: string;
}

View file

@ -9,6 +9,7 @@ export type User = {
uuid: string;
public_profile: boolean;
has_password: boolean;
disable_password: boolean;
};
export type Adventure = {

View file

@ -428,7 +428,15 @@
"documentation_link": "Documentation Link",
"launch_account_connections": "Launch Account Connections",
"password_too_short": "Password must be at least 6 characters",
"add_email": "Add Email"
"add_email": "Add Email",
"password_disable": "Disable Password Authentication",
"password_disable_desc": "Disabling password authentication will prevent you from logging in with a password. You will need to use a social or OIDC provider to log in. Should your social provider be unlinked, password authentication will be automatically re-enabled even if this setting is disabled.",
"disable_password": "Disable Password",
"password_enabled": "Password authentication enabled",
"password_disabled": "Password authentication disabled",
"password_disable_warning": "Currently, password authentication is disabled. Login via a social or OIDC provider is required.",
"password_disabled_error": "Error disabling password authentication. Make sure a social or OIDC provider is linked to your account.",
"password_enabled_error": "Error enabling password authentication."
},
"collection": {
"collection_created": "Collection created successfully!",

View file

@ -6,7 +6,7 @@ import { json } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export async function GET(event) {
const { url, params, request, fetch, cookies } = event;
const searchParam = url.search ? `${url.search}&format=json` : '?format=json';
const searchParam = url.search ? `${url.search}` : '';
return handleRequest(url, params, request, fetch, cookies, searchParam);
}
@ -17,13 +17,13 @@ export async function POST({ url, params, request, fetch, cookies }) {
}
export async function PATCH({ url, params, request, fetch, cookies }) {
const searchParam = url.search ? `${url.search}&format=json` : '?format=json';
return handleRequest(url, params, request, fetch, cookies, searchParam, true);
const searchParam = url.search ? `${url.search}` : '';
return handleRequest(url, params, request, fetch, cookies, searchParam, false);
}
export async function PUT({ url, params, request, fetch, cookies }) {
const searchParam = url.search ? `${url.search}&format=json` : '?format=json';
return handleRequest(url, params, request, fetch, cookies, searchParam, true);
const searchParam = url.search ? `${url.search}` : '';
return handleRequest(url, params, request, fetch, cookies, searchParam, false);
}
export async function DELETE({ url, params, request, fetch, cookies }) {
@ -43,13 +43,15 @@ async function handleRequest(
const path = params.path;
let targetUrl = `${endpoint}/auth/${path}`;
const add_trailing_slash_list = ['disable-password'];
// Ensure the path ends with a trailing slash
if (requreTrailingSlash && !targetUrl.endsWith('/')) {
if ((requreTrailingSlash && !targetUrl.endsWith('/')) || add_trailing_slash_list.includes(path)) {
targetUrl += '/';
}
// Append query parameters to the path correctly
targetUrl += searchParam; // This will add ?format=json or &format=json to the URL
targetUrl += searchParam; // This will add or to the URL
const headers = new Headers(request.headers);

View file

@ -9,7 +9,6 @@
import TotpModal from '$lib/components/TOTPModal.svelte';
import { appTitle, appVersion } from '$lib/config.js';
import ImmichLogo from '$lib/assets/immich.svg';
import { goto } from '$app/navigation';
export let data;
console.log(data);
@ -20,6 +19,8 @@
emails = data.props.emails;
}
let new_password_disable_setting: boolean = false;
let new_email: string = '';
let public_url: string = data.props.publicUrl;
let immichIntegration = data.props.immichIntegration;
@ -87,8 +88,36 @@
}
}
async function disablePassword() {
if (user.disable_password) {
let res = await fetch('/auth/disable-password/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
if (res.ok) {
addToast('success', $t('settings.password_disabled'));
} else {
addToast('error', $t('settings.password_disabled_error'));
}
} else {
let res = await fetch('/auth/disable-password/', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
});
if (res.ok) {
addToast('success', $t('settings.password_enabled'));
} else {
addToast('error', $t('settings.password_enabled_error'));
}
}
}
async function verifyEmail(email: { email: any; verified?: boolean; primary?: boolean }) {
let res = await fetch('/auth/browser/v1/account/email/', {
let res = await fetch('/auth/browser/v1/account/email', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
@ -103,7 +132,7 @@
}
async function addEmail() {
let res = await fetch('/auth/browser/v1/account/email/', {
let res = await fetch('/auth/browser/v1/account/email', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@ -122,7 +151,7 @@
}
async function primaryEmail(email: { email: any; verified?: boolean; primary?: boolean }) {
let res = await fetch('/auth/browser/v1/account/email/', {
let res = await fetch('/auth/browser/v1/account/email', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
@ -490,6 +519,38 @@
href={`${public_url}/accounts/social/connections/`}
target="_blank">{$t('settings.launch_account_connections')}</a
>
<div class="mt-8">
<h2 class="text-2xl font-semibold text-center">{$t('settings.password_disable')}</h2>
<p>{$t('settings.password_disable_desc')}</p>
<div class="flex flex-col items-center mt-4">
<input
type="checkbox"
id="disable_password"
name="disable_password"
bind:checked={user.disable_password}
class="checkbox checkbox-primary"
/>
<label for="disable_password" class="ml-2 text-sm text-neutral-content"
>{$t('settings.disable_password')}</label
>
<button class="btn btn-primary mt-4" on:click={disablePassword}
>{$t('settings.update')}</button
>
{#if user.disable_password}
<div class="badge badge-error mt-2">{$t('settings.password_disabled')}</div>
{/if}
{#if !user.disable_password}
<div class="badge badge-success mt-2">{$t('settings.password_enabled')}</div>
{/if}
{#if user.disable_password}
<div class="alert alert-warning mt-4">
{$t('settings.password_disable_warning')}
</div>
{/if}
</div>
</div>
</div>
</section>