183 lines
4.3 KiB
TypeScript
183 lines
4.3 KiB
TypeScript
|
import request from "../../helper/request";
|
||
|
import sha from "../../helper/sha512";
|
||
|
import { setCookie, getCookie } from "../../helper/cookie";
|
||
|
|
||
|
export interface TwoFactor {
|
||
|
id: string;
|
||
|
name: string;
|
||
|
type: TFATypes;
|
||
|
}
|
||
|
|
||
|
export enum TFATypes {
|
||
|
OTC,
|
||
|
BACKUP_CODE,
|
||
|
U2F,
|
||
|
APP_ALLOW,
|
||
|
}
|
||
|
|
||
|
// const Api = {
|
||
|
// // twofactor: [{
|
||
|
// // id: "1",
|
||
|
// // name: "Backup Codes",
|
||
|
// // type: TFATypes.BACKUP_CODE
|
||
|
// // }, {
|
||
|
// // id: "2",
|
||
|
// // name: "YubiKey",
|
||
|
// // type: TFATypes.U2F
|
||
|
// // }, {
|
||
|
// // id: "3",
|
||
|
// // name: "Authenticator",
|
||
|
// // type: TFATypes.OTC
|
||
|
// // }] as TwoFactor[],
|
||
|
|
||
|
// }
|
||
|
|
||
|
export interface IToken {
|
||
|
token: string;
|
||
|
expires: string;
|
||
|
}
|
||
|
|
||
|
function makeid(length) {
|
||
|
var result = "";
|
||
|
var characters =
|
||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||
|
var charactersLength = characters.length;
|
||
|
for (var i = 0; i < length; i++) {
|
||
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
export default class Api {
|
||
|
static salt: string;
|
||
|
static login: IToken;
|
||
|
static special: IToken;
|
||
|
static username: string;
|
||
|
|
||
|
static twofactor: any[];
|
||
|
|
||
|
static getUsername() {
|
||
|
return this.username || getCookie("username");
|
||
|
}
|
||
|
|
||
|
static async setUsername(
|
||
|
username: string
|
||
|
): Promise<{ error: string | undefined }> {
|
||
|
return request(
|
||
|
"/api/user/login",
|
||
|
{
|
||
|
type: "username",
|
||
|
username,
|
||
|
},
|
||
|
"POST"
|
||
|
)
|
||
|
.then((res) => {
|
||
|
this.salt = res.salt;
|
||
|
this.username = username;
|
||
|
return {
|
||
|
error: undefined,
|
||
|
};
|
||
|
})
|
||
|
.catch((err) => {
|
||
|
let error = err.message;
|
||
|
return { error };
|
||
|
});
|
||
|
}
|
||
|
|
||
|
static async setPassword(
|
||
|
password: string
|
||
|
): Promise<{ error: string | undefined; twofactor?: any }> {
|
||
|
const date = new Date().valueOf();
|
||
|
let pw = sha(sha(this.salt + password) + date.toString());
|
||
|
return request(
|
||
|
"/api/user/login",
|
||
|
{
|
||
|
type: "password",
|
||
|
},
|
||
|
"POST",
|
||
|
{
|
||
|
username: this.username,
|
||
|
password: pw,
|
||
|
date,
|
||
|
}
|
||
|
)
|
||
|
.then(({ login, special, tfa }) => {
|
||
|
this.login = login;
|
||
|
this.special = special;
|
||
|
|
||
|
if (tfa && Array.isArray(tfa) && tfa.length > 0)
|
||
|
this.twofactor = tfa;
|
||
|
else this.twofactor = undefined;
|
||
|
|
||
|
return {
|
||
|
error: undefined,
|
||
|
};
|
||
|
})
|
||
|
.catch((err) => {
|
||
|
let error = err.message;
|
||
|
return { error };
|
||
|
});
|
||
|
}
|
||
|
|
||
|
static gettok() {
|
||
|
return {
|
||
|
login: this.login.token,
|
||
|
special: this.special.token,
|
||
|
};
|
||
|
}
|
||
|
|
||
|
static async sendBackup(id: string, code: string) {
|
||
|
return request("/api/user/twofactor/backup", this.gettok(), "PUT", {
|
||
|
code,
|
||
|
id,
|
||
|
})
|
||
|
.then(({ login_exp, special_exp }) => {
|
||
|
this.login.expires = login_exp;
|
||
|
this.special.expires = special_exp;
|
||
|
return {};
|
||
|
})
|
||
|
.catch((err) => ({ error: err.message }));
|
||
|
}
|
||
|
|
||
|
static async sendOTC(id: string, code: string) {
|
||
|
return request("/api/user/twofactor/otc", this.gettok(), "PUT", {
|
||
|
code,
|
||
|
id,
|
||
|
})
|
||
|
.then(({ login_exp, special_exp }) => {
|
||
|
this.login.expires = login_exp;
|
||
|
this.special.expires = special_exp;
|
||
|
return {};
|
||
|
})
|
||
|
.catch((error) => ({ error: error.message }));
|
||
|
}
|
||
|
|
||
|
static finish() {
|
||
|
let d = new Date();
|
||
|
d.setTime(d.getTime() + 30 * 24 * 60 * 60 * 1000); //Keep the username 30 days
|
||
|
setCookie("username", this.username, d.toUTCString());
|
||
|
|
||
|
setCookie(
|
||
|
"login",
|
||
|
this.login.token,
|
||
|
new Date(this.login.expires).toUTCString()
|
||
|
);
|
||
|
setCookie(
|
||
|
"special",
|
||
|
this.special.token,
|
||
|
new Date(this.special.expires).toUTCString()
|
||
|
);
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
}
|