Skip to content
Merged
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": ""
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "أنت غير مسجل الدخول. يرجى تسجيل الدخول للمتابعة.",
"session_expired": "تم تسجيل خروجك لانتهاء صلاحية جلستك.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": "Vaše relace byla uzamčena v jiné kartě."
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "Nejste přihlášeni. Pro pokračování se prosím přihlaste.",
"session_expired": "Byli jste odhlášeni, protože vaše relace vypršela.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": "Deine Session wurde in einem anderem Browsertab gesperrt."
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "Du bist nicht angemeldet. Bitte melde Dich an, um fortzufahren.",
"session_expired": "Deine Sitzung ist abgelaufen, du wurdest abgemeldet.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": "Your session was locked in another tab."
},
"info": {
"signups_closed": "New sign-ups are currently restricted. Please try again later."
},
"warning": {
"not_signed_in": "You are not signed in. Please sign in to continue.",
"session_expired": "You have been logged out because your session has expired.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": "Tu sesión fue bloqueada."
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "No has iniciado sesión. Por favor, inicia sesión para continuar.",
"session_expired": "Has sido desconectado porque tu sesión ha expirado.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": "Votre session a été verrouillée dans un autre onglet."
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "Vous n'êtes pas connecté. Veuillez vous connecter pour continuer.",
"session_expired": "Vous avez été déconnecté car votre session a expiré.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": ""
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "आपने साइन इन नहीं किया है। कृपया जारी रखने के लिए साइन इन करें।",
"session_expired": "आपकी सत्र अवधि समाप्त होने के कारण आपको लॉग आउट कर दिया गया है।",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": ""
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "Non sei connesso. Effettua il login per continuare.",
"session_expired": "Sei stato disconnesso perché la tua sessione è scaduta.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": "別のタブで操作が行われたため、このセッションはロックされました。"
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "サインインしていません。続行するにはサインインしてください。",
"session_expired": "セッションの有効期限が切れました。ログアウトされました。",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/ko-KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": "다른 탭에서 세션이 잠겼습니다."
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "로그인되어 있지 않습니다. 계속하려면 로그인해 주세요.",
"session_expired": "세션이 만료되어 로그아웃되었습니다.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": ""
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "Nie jesteś zalogowany. Zaloguj się, aby kontynuować.",
"session_expired": "Zostałeś wylogowany, ponieważ Twoja sesja wygasła.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": ""
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "Você não está logado. Por favor, faça login para continuar.",
"session_expired": "Você foi desconectado porque sua sessão expirou.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": "Сессия заблокирована"
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "Вы не вошли в систему. Пожалуйста, войдите, чтобы продолжить.",
"session_expired": "Вы были автоматически выведены из системы, так как срок действия вашей сессии истек.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": ""
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "Bạn chưa đăng nhập. Vui lòng đăng nhập để tiếp tục.",
"session_expired": "Bạn đã bị đăng xuất vì phiên của bạn đã hết hạn.",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/lib/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@
"message": {
"session_locked": "你的会话已在另一个标签页中被锁定。"
},
"info": {
"signups_closed": ""
},
"warning": {
"not_signed_in": "你尚未登录。请先登录以继续。",
"session_expired": "由于会话已过期,你已被登出。",
Expand Down
19 changes: 19 additions & 0 deletions src/frontend/src/lib/services/auth.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,25 @@ export const errorSignOut = (text: string): Promise<void> => {
});
};

export const infoSignOut = ({
text,
source = ''
}: {
text: string;
source?: string;
}): Promise<void> => {
trackSignOut({
name: TRACK_SIGN_OUT_SUCCESS,
meta: { reason: 'info', text, source }
});
return logout({
msg: {
text,
level: 'info'
}
});
};

export const warnSignOut = (text: string): Promise<void> => {
trackSignOut({
name: TRACK_SIGN_OUT_WITH_WARNING,
Expand Down
15 changes: 13 additions & 2 deletions src/frontend/src/lib/services/loader.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '$lib/derived/networks.derived';
import { loadAddresses } from '$lib/services/addresses.services';
import { trackRateLimited } from '$lib/services/analytics.services';
import { errorSignOut, nullishSignOut, signOut } from '$lib/services/auth.services';
import { errorSignOut, infoSignOut, nullishSignOut, signOut } from '$lib/services/auth.services';
import { loadUserProfile } from '$lib/services/load-user-profile.services';
import { authStore } from '$lib/stores/auth.store';
import { i18n } from '$lib/stores/i18n.store';
Expand Down Expand Up @@ -86,9 +86,20 @@ export const initLoader = async ({

// The user profile settings will define the enabled/disabled networks.
// So we need to load it first to enable/disable the rest of the services.
const { success: userProfileSuccess } = await loadUserProfile({ identity });
const { success: userProfileSuccess, err: userProfileError } = await loadUserProfile({
identity
});
Comment thread
AntonioVentilii marked this conversation as resolved.

if (!userProfileSuccess) {
if (userProfileError === 'signups-closed') {
await infoSignOut({
text: get(i18n).auth.info.signups_closed,
Comment thread
AntonioVentilii marked this conversation as resolved.
source: 'signups-closed'
});

return;
Comment thread
AntonioVentilii marked this conversation as resolved.
}
Comment thread
AntonioVentilii marked this conversation as resolved.

await signOut({});
return;
}
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/lib/types/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ interface I18nAuth {
sign_in_with_microsoft: string;
};
message: { session_locked: string };
info: { signups_closed: string };
warning: { not_signed_in: string; session_expired: string; reload_and_retry: string };
error: {
no_internet_identity: string;
Expand Down
37 changes: 37 additions & 0 deletions src/frontend/src/tests/lib/services/auth.services.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { trackEvent } from '$lib/services/analytics.services';
import {
errorSignOut,
idleSignOut,
infoSignOut,
lockSession,
nullishSignOut,
signOut,
Expand Down Expand Up @@ -417,6 +418,42 @@ describe('auth.services', () => {
});
});

describe('infoSignOut', () => {
const mockText = 'New sign-ups are currently restricted.';

beforeEach(() => {
vi.clearAllMocks();
});

it('should track the sign out event with the provided source', async () => {
await infoSignOut({ text: mockText, source: 'signups-closed' });

expect(trackEvent).toHaveBeenCalledExactlyOnceWith({
name: TRACK_SIGN_OUT_SUCCESS,
metadata: {
reason: 'info',
level: '',
text: mockText,
source: 'signups-closed',
resetUrl: 'false',
clearStorages: 'true'
}
});
});

it('should append the message to the reload URL with level=info', async () => {
await infoSignOut({ text: mockText });

expect(window.history.replaceState).toHaveBeenCalledExactlyOnceWith(
{},
'',
new URL(
`${rootLocation}?msg=${encodeURI(encodeURI(mockText))}&level=info&${PARAM_DELETE_IDB_CACHE}=true`
)
);
});
});

describe('nullishSignOut', () => {
const expectedText = en.auth.warning.not_signed_in;

Expand Down
20 changes: 18 additions & 2 deletions src/frontend/src/tests/lib/services/loader.services.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ZERO } from '$lib/constants/app.constants';
import { loadAddresses } from '$lib/services/addresses.services';
import { trackRateLimited } from '$lib/services/analytics.services';
import * as authServices from '$lib/services/auth.services';
import { nullishSignOut, signOut } from '$lib/services/auth.services';
import { infoSignOut, nullishSignOut, signOut } from '$lib/services/auth.services';
import { loadUserProfile } from '$lib/services/load-user-profile.services';
import { initLoader, initSignerAllowance } from '$lib/services/loader.services';
import { authStore } from '$lib/stores/auth.store';
Expand Down Expand Up @@ -137,6 +137,7 @@ describe('loader.services', () => {
vi.resetAllMocks();

vi.spyOn(authServices, 'signOut').mockImplementation(vi.fn());
vi.spyOn(authServices, 'infoSignOut').mockImplementation(vi.fn());
vi.spyOn(authServices, 'nullishSignOut').mockImplementation(vi.fn());
vi.spyOn(api, 'allowSigning').mockResolvedValue(mockExecutedOutcome);

Expand All @@ -160,13 +161,28 @@ describe('loader.services', () => {
});

it('should sign out if the user profile is not loaded', async () => {
vi.mocked(loadUserProfile).mockResolvedValueOnce({ success: false });
vi.mocked(loadUserProfile).mockResolvedValueOnce({ success: false, err: 'unknown' });

await initLoader(mockParams);

expect(signOut).toHaveBeenCalledOnce();
});

it('should sign out via infoSignOut when signups are closed', async () => {
vi.mocked(loadUserProfile).mockResolvedValueOnce({
success: false,
err: 'signups-closed'
});

await initLoader(mockParams);

expect(infoSignOut).toHaveBeenCalledExactlyOnceWith({
text: expect.stringMatching(/sign-?ups/i),
source: 'signups-closed'
});
Comment thread
AntonioVentilii marked this conversation as resolved.
expect(signOut).not.toHaveBeenCalled();
});

it('should load addresses from the backend', async () => {
await initLoader(mockParams);

Expand Down
Loading