Add JRPC API, reworked Login and User pages
This commit is contained in:
183
Frontend/src/pages/login/state.ts
Normal file
183
Frontend/src/pages/login/state.ts
Normal file
@ -0,0 +1,183 @@
|
||||
import type { LoginState } from "@hibas123/openauth-internalapi";
|
||||
import { derived, get, writable } from "svelte/store";
|
||||
import InternalAPI from "../../helper/api";
|
||||
import sha from "../../helper/sha512";
|
||||
|
||||
interface LocalLoginState extends LoginState {
|
||||
loading: boolean;
|
||||
error?: string;
|
||||
username?: string;
|
||||
}
|
||||
|
||||
class LoginStore {
|
||||
state = writable<LocalLoginState>({
|
||||
username: undefined,
|
||||
password: false,
|
||||
passwordSalt: undefined,
|
||||
requireTwoFactor: [],
|
||||
success: false,
|
||||
loading: true,
|
||||
error: undefined
|
||||
})
|
||||
|
||||
isFinished = derived(this.state, $state => $state.success);
|
||||
|
||||
constructor() {
|
||||
this.state.subscribe((state) => {
|
||||
if (state.success) {
|
||||
setTimeout(() => {
|
||||
this.finish();
|
||||
}, 2000);
|
||||
}
|
||||
})
|
||||
this.getState();
|
||||
}
|
||||
|
||||
setLoading(loading: boolean) {
|
||||
this.state.update(current => ({
|
||||
...current,
|
||||
loading,
|
||||
error: loading ? undefined : current.error,
|
||||
}));
|
||||
}
|
||||
|
||||
setError(error: string) {
|
||||
this.state.update(current => ({
|
||||
...current,
|
||||
error,
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
async getState() {
|
||||
try {
|
||||
this.setLoading(true);
|
||||
|
||||
let state = await InternalAPI.Login.GetState();
|
||||
this.state.update(current => ({
|
||||
...current,
|
||||
...state,
|
||||
}));
|
||||
} catch (err) {
|
||||
this.setError(err.message);
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
async setUsername(username: string) {
|
||||
try {
|
||||
this.setLoading(true);
|
||||
|
||||
let state = await InternalAPI.Login.Start(username);
|
||||
this.state.update(current => ({
|
||||
...current,
|
||||
...state,
|
||||
username
|
||||
}));
|
||||
} catch (err) {
|
||||
this.setError(err.message);
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async setPassword(password: string) {
|
||||
try {
|
||||
this.setLoading(true);
|
||||
|
||||
const date = new Date().valueOf();
|
||||
let salt = get(this.state).passwordSalt
|
||||
let pw = sha(sha(salt + password) + date.toString());
|
||||
|
||||
let state = await InternalAPI.Login.UsePassword(pw, date);
|
||||
this.state.update(current => ({
|
||||
...current,
|
||||
...state,
|
||||
}));
|
||||
} catch (err) {
|
||||
this.setError(err.message);
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
async useTOTP(id: string, code: string) {
|
||||
try {
|
||||
this.setLoading(true);
|
||||
|
||||
let state = await InternalAPI.Login.UseTOTP(id, code);
|
||||
this.state.update(current => ({
|
||||
...current,
|
||||
...state,
|
||||
}));
|
||||
} catch (err) {
|
||||
this.setError(err.message);
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
async useBackupCode(id: string, code: string) {
|
||||
try {
|
||||
this.setLoading(true);
|
||||
|
||||
let state = await InternalAPI.Login.UseBackupCode(id, code);
|
||||
this.state.update(current => ({
|
||||
...current,
|
||||
...state,
|
||||
}));
|
||||
} catch (err) {
|
||||
this.setError(err.message);
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
async getWebAuthnChallenge(id: string) {
|
||||
try {
|
||||
this.setLoading(true);
|
||||
|
||||
let challenge = await InternalAPI.Login.GetWebAuthnChallenge(id);
|
||||
return challenge;
|
||||
} catch (err) {
|
||||
this.setError(err.message);
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
async useWebAuthn(id: string, response: any) {
|
||||
try {
|
||||
this.setLoading(true);
|
||||
|
||||
let state = await InternalAPI.Login.UseWebAuthn(id, JSON.stringify(response));
|
||||
this.state.update(current => ({
|
||||
...current,
|
||||
...state,
|
||||
}));
|
||||
} catch (err) {
|
||||
this.setError(err.message);
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
async finish() {
|
||||
let url = new URL(window.location.href);
|
||||
let state = url.searchParams.get("state");
|
||||
let red = "/";
|
||||
|
||||
if (state) {
|
||||
let base64 = url.searchParams.get("base64");
|
||||
if (base64) red = atob(state);
|
||||
else red = state;
|
||||
}
|
||||
setTimeout(() => (window.location.href = red), 200);
|
||||
}
|
||||
}
|
||||
|
||||
const loginState = new LoginStore();
|
||||
|
||||
export default loginState;
|
Reference in New Issue
Block a user