blob: 07797a4cd84958a6678916032de1630a48e9dc6c [file] [log] [blame]
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -04001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
simon94fe53e2022-11-10 12:51:58 -050018import axios from 'axios';
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -040019import { passwordStrength } from 'check-password-strength';
Misha Krieger-Raynauldcfa44302022-11-30 18:36:36 -050020import { AccessToken, HttpStatusCode } from 'jami-web-common';
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -040021
simonf929a362022-11-18 16:53:45 -050022import { PasswordStrength } from '../enums/passwordStrength';
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040023import { apiUrl } from './constants';
Gabriel Rochon7057b4f2022-11-21 13:28:01 -050024import { InvalidCredentials, InvalidPassword, UsernameNotFound } from './errors';
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -040025
26interface PasswordStrengthResult {
27 id: number;
28 value: string;
29 contains: string[];
30 length: number;
31}
32
33export interface PasswordCheckResult {
34 strong: boolean;
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040035 valueCode: StrengthValueCode;
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -040036}
37
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040038export type StrengthValueCode = 'default' | 'too_weak' | 'weak' | 'medium' | 'strong';
Gabriel Rochon7057b4f2022-11-21 13:28:01 -050039export type LoginMethod = 'Jami' | 'JAMS';
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040040
41const idToStrengthValueCode: StrengthValueCode[] = ['too_weak', 'weak', 'medium', 'strong'];
42
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -040043export async function isNameRegistered(name: string): Promise<boolean> {
simon94fe53e2022-11-10 12:51:58 -050044 try {
Misha Krieger-Raynauld46e9d242022-11-12 18:02:43 -050045 await axios.get(`/ns/username/${name}`, { baseURL: apiUrl });
simon94fe53e2022-11-10 12:51:58 -050046 return true;
47 } catch (e: any) {
48 if (e.response?.status !== HttpStatusCode.NotFound) {
49 throw e;
50 }
51 return false;
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -040052 }
53}
54
55export function checkPasswordStrength(password: string): PasswordCheckResult {
56 const strengthResult: PasswordStrengthResult = passwordStrength(password);
57
simon94fe53e2022-11-10 12:51:58 -050058 return {
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -040059 strong: strengthResult.id === PasswordStrength.Strong.valueOf(),
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040060 valueCode: idToStrengthValueCode[strengthResult.id] ?? 'default',
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -040061 };
Michelle Sepkap Simebff70eb2022-10-17 15:01:14 -040062}
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040063
Gabriel Rochon7057b4f2022-11-21 13:28:01 -050064export async function registerUser(username: string, password: string, isJams: boolean): Promise<void> {
65 try {
66 await axios.post('/auth/new-account', { username, password, isJams }, { baseURL: apiUrl });
67 } catch (e: any) {
68 if (e.response?.status === HttpStatusCode.Unauthorized) {
69 throw new InvalidCredentials();
70 } else {
71 throw e;
72 }
73 }
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040074}
75
Gabriel Rochon7057b4f2022-11-21 13:28:01 -050076export async function loginUser(username: string, password: string, isJams: boolean): Promise<string> {
simon94fe53e2022-11-10 12:51:58 -050077 try {
Misha Krieger-Raynauldcfa44302022-11-30 18:36:36 -050078 const { data } = await axios.post<AccessToken>('/auth/login', { username, password, isJams }, { baseURL: apiUrl });
simon94fe53e2022-11-10 12:51:58 -050079 return data.accessToken;
80 } catch (e: any) {
81 switch (e.response?.status) {
82 case HttpStatusCode.NotFound:
83 throw new UsernameNotFound();
84 case HttpStatusCode.Unauthorized:
85 throw new InvalidPassword();
86 default:
87 throw e;
88 }
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040089 }
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040090}
91
Michelle Sepkap Simedd82cbf2022-11-17 23:31:49 -050092export function getAccessToken(): string | undefined {
93 return localStorage.getItem('accessToken') ?? undefined;
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040094}
95
96export function setAccessToken(accessToken: string): void {
97 localStorage.setItem('accessToken', accessToken);
98}