Skip to content

Commit

Permalink
Make the lang setting work
Browse files Browse the repository at this point in the history
Remove debug line
  • Loading branch information
monsieurswag committed Oct 2, 2024
1 parent 2159b94 commit c6397e4
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 37 deletions.
8 changes: 7 additions & 1 deletion backend/global_settings/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@

from iam.sso.views import SSOSettingsViewSet

from .views import GlobalSettingsViewSet, get_sso_info, update_general_settings
from .views import (
GlobalSettingsViewSet,
get_sso_info,
update_general_settings,
get_general_settings,
)
from .routers import DefaultSettingsRouter


Expand All @@ -21,6 +26,7 @@
# This route should ideally be placed under the routes of the routers, but the DefaultRouter usage overwrite the route and makes it inaccessible.
# Could we use DefaultSettingsRouter to register the "global" route to fix that ?
path(r"general/update/", update_general_settings, name="update_general_settings"),
path(r"general/info/", get_general_settings, name="get_general_settings"),
path(r"", include(router.urls)),
path(r"", include(settings_router.urls)),
path(r"sso/info/", get_sso_info, name="get_sso_info"),
Expand Down
19 changes: 19 additions & 0 deletions backend/global_settings/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,25 @@ def update(self, request, *args, **kwargs):
UPDATABLE_GENERAL_SETTINGS = frozenset(
["lang"]
) # This represents the list of "general" GlobalSettings an admin has the right to change.
PUBLIC_GENERAL_SETTINGS = [
"lang"
] # List of general settings accessible by anyone (non-sensitive general settings).


@api_view(["GET"])
@permission_classes([permissions.AllowAny])
def get_general_settings(request):
"""
API endpoint to get the general settings.
"""
general_settings = GlobalSettings.objects.filter(name="general").first()
if general_settings is None:
return {}

public_settings = {
key: general_settings.value.get(key) for key in PUBLIC_GENERAL_SETTINGS
}
return Response(public_settings)


@api_view(["PATCH"])
Expand Down
44 changes: 33 additions & 11 deletions frontend/src/hooks.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { languageTag, setLanguageTag } from '$paraglide/runtime';

import { loadFeatureFlags } from '$lib/feature-flags';

let generalSettings = {};

async function ensureCsrfToken(event: RequestEvent): Promise<string> {
let csrfToken = event.cookies.get('csrftoken') || '';
if (!csrfToken) {
Expand All @@ -28,23 +30,43 @@ async function ensureCsrfToken(event: RequestEvent): Promise<string> {

async function validateUserSession(event: RequestEvent): Promise<User | null> {
const token = event.cookies.get('token');
if (!token) return null;
const requestList = [fetch(`${BASE_API_URL}/settings/general/info/`)];
if (token) {
requestList.push(
fetch(`${BASE_API_URL}/iam/current-user/`, {
credentials: 'include',
headers: {
'content-type': 'application/json',
Authorization: `Token ${token}`
}
})
);
}

const res = await fetch(`${BASE_API_URL}/iam/current-user/`, {
credentials: 'include',
headers: {
'content-type': 'application/json',
Authorization: `Token ${token}`
}
});
const responseList = await Promise.all(requestList);
const settingsRes = responseList[0];
const newGeneralSettings = await settingsRes.json();
generalSettings = newGeneralSettings;

if (!event.cookies.get('ciso_lang')) {
event.cookies.set('ciso_lang', generalSettings.lang || 'en', {
httpOnly: false,
sameSite: 'lax',
path: '/',
secure: true
});
}

if (!token) return null;

if (!res.ok) {
const userRes = responseList[1];
if (!userRes.ok) {
event.cookies.delete('token', {
path: '/'
});
redirect(302, `/login?next=${event.url.pathname}`);
}
return res.json();
return userRes.json();
}

export const handle: Handle = async ({ event, resolve }) => {
Expand All @@ -56,7 +78,7 @@ export const handle: Handle = async ({ event, resolve }) => {

const errorId = new URL(event.request.url).searchParams.get('error');
if (errorId) {
setLanguageTag(event.cookies.get('ciso_lang') || 'en');
setLanguageTag(event.cookies.get('ciso_lang') || generalSettings.lang || 'en');
setFlash({ type: 'error', message: safeTranslate(errorId) }, event);
redirect(302, '/login');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import Select from '../Select.svelte';
import type { SuperValidated } from 'sveltekit-superforms';
import type { ModelInfo, CacheLock } from '$lib/utils/types';
import { availableLanguageTags, languageTag, setLanguageTag } from '$paraglide/runtime';
import { availableLanguageTags } from '$paraglide/runtime';
import { LOCALE_DISPLAY_MAP } from '$lib/utils/constants';
import * as m from '$paraglide/messages.js';
export let form: SuperValidated<any>;
export let model: ModelInfo;
export let cacheLocks: Record<string, CacheLock> = {};
Expand Down
1 change: 0 additions & 1 deletion frontend/src/lib/components/Forms/Select.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
{@const defaultValue = blank ? '' : null}
<option value={defaultValue} selected>--</option>
{/if}
{JSON.stringify(options)}
{#each options as option}
<option value={option.value} style="background-color: {color_map[option.value]}">
{safeTranslate(option.label)}
Expand Down
46 changes: 27 additions & 19 deletions frontend/src/routes/(app)/(internal)/settings/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,42 @@ export const load: PageServerLoad = async ({ fetch }) => {

const selectOptions: Record<string, any> = {};

const ssoMmodel = getModelInfo('sso-settings');
const ssoModel = getModelInfo('sso-settings');
const generalSettingModel = getModelInfo('general-settings');

if (ssoMmodel.selectFields) {
for (const selectField of ssoMmodel.selectFields) {
const url = `${BASE_API_URL}/settings/sso/${selectField.field}/`;
const response = await fetch(url);
if (response.ok) {
selectOptions[selectField.field] = await response.json().then((data) =>
Object.entries(data).map(([key, value]) => ({
label: value,
value: key
}))
);
} else {
console.error(`Failed to fetch data for ${selectField.field}: ${response.statusText}`);
}
}
const requestList = [fetch(`${BASE_API_URL}/settings/general/info/`)];

const selectFields = ssoModel.selectFields ?? [];
for (const selectField of selectFields) {
const field = selectField.field;
const url = `${BASE_API_URL}/settings/sso/${field}/`;
requestList.push(fetch(url).then((response) => [response, field]));
}

ssoMmodel.selectOptions = selectOptions;
const responseList = await Promise.all(requestList);
const generalSettingResponse = responseList[0];
for (let i = 1; i < responseList.length; i++) {
const [response, field] = responseList[i];
if (response.ok) {
selectOptions[field] = await response.json().then((data) =>
Object.entries(data).map(([key, value]) => ({
label: value,
value: key
}))
);
} else {
console.error(`Failed to fetch data for ${selectField.field}: ${response.statusText}`);
}
}

ssoModel.selectOptions = selectOptions;
const ssoForm = await superValidate(settings, zod(SSOSettingsSchema), { errors: false });
const generalSettingForm = await superValidate(settings, zod(GeneralSettingsSchema), {
const generalSettings = await generalSettingResponse.json();
const generalSettingForm = await superValidate(generalSettings, zod(GeneralSettingsSchema), {
errors: false
});

return { settings, ssoForm, ssoMmodel, generalSettingForm, generalSettingModel };
return { settings, ssoForm, ssoModel, generalSettingForm, generalSettingModel };
};

export const actions: Actions = {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/(app)/(internal)/settings/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
{#if tabSet === 0}
<div>
<span class="text-gray-500">{m.ssoSettingsDescription()}</span>
<ModelForm form={data.ssoForm} model={data.ssoMmodel} cancelButton={false} action="?/sso" />
<ModelForm form={data.ssoForm} model={data.ssoModel} cancelButton={false} action="?/sso" />
</div>
{:else if tabSet === 1}
<div>
Expand Down
1 change: 0 additions & 1 deletion frontend/src/routes/(app)/+layout.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@ export const load = loadFlash(async ({ locals, url, cookies, request }) => {
});
}
}
setLanguageTag(cookies.get('ciso_lang') || sourceLanguageTag);
return { user: locals.user };
}) satisfies LayoutServerLoad;
3 changes: 1 addition & 2 deletions frontend/src/routes/ParaglideJsProvider.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
onMount(() => {
// const valueFromSession = sessionStorage.getItem('lang') || sourceLanguageTag;
const valueFromCookies = getCookie('ciso_lang') || sourceLanguageTag;
const valueFromCookies = getCookie('ciso_lang') || languageTag();
// @ts-ignore
setCookie('ciso_lang', valueFromCookies);
setLanguageTag(valueFromCookies);
});
Expand Down

0 comments on commit c6397e4

Please sign in to comment.