Compare commits
88 Commits
Author | SHA1 | Date |
---|---|---|
Derrick Hammer | 456db25ad7 | |
Derrick Hammer | 2744b40cfa | |
Derrick Hammer | 080fea1b1e | |
Derrick Hammer | afa853aa12 | |
Derrick Hammer | 1f69c9c1cc | |
Derrick Hammer | db2212ab70 | |
Derrick Hammer | dcd1fdc705 | |
Derrick Hammer | 574ef1ddb1 | |
Derrick Hammer | 76751db499 | |
Derrick Hammer | 8296e7410d | |
Derrick Hammer | 1bf1360937 | |
Derrick Hammer | 2ee92db9ce | |
Derrick Hammer | 7239cc7ba1 | |
Derrick Hammer | 08d24eebf4 | |
Derrick Hammer | b74ea88900 | |
Derrick Hammer | 61b8b3b554 | |
Derrick Hammer | 93a7360537 | |
Derrick Hammer | d5b27e946c | |
Derrick Hammer | 3b63255b75 | |
Derrick Hammer | 1b136d2089 | |
Derrick Hammer | f95fb116a8 | |
Derrick Hammer | 01c66456a8 | |
Derrick Hammer | 9131fc8b96 | |
Derrick Hammer | 8ed63175bc | |
Derrick Hammer | 99a92b1625 | |
Derrick Hammer | ccc30a2077 | |
Derrick Hammer | c5396b5535 | |
Derrick Hammer | 8431f5c9f8 | |
Derrick Hammer | a508347fb1 | |
Derrick Hammer | 55fc51ad0a | |
Derrick Hammer | b7a9484785 | |
Derrick Hammer | 7a3248b21b | |
Derrick Hammer | ef3d0d3fbc | |
Derrick Hammer | 788e424841 | |
Derrick Hammer | c0345dec11 | |
Derrick Hammer | 5b04f7ecaf | |
Derrick Hammer | bc5f143ae6 | |
Derrick Hammer | 845c47fef9 | |
Derrick Hammer | 6163b40d7b | |
Derrick Hammer | 0e09f2ecb3 | |
Derrick Hammer | 3b2d839f04 | |
Derrick Hammer | 271917540d | |
Derrick Hammer | 8cf56b4751 | |
Derrick Hammer | f99c51e4df | |
Derrick Hammer | 1f68b13180 | |
Derrick Hammer | 51cb8d7a90 | |
Derrick Hammer | 8911251288 | |
Derrick Hammer | a135201dfb | |
Derrick Hammer | 14c854c455 | |
Derrick Hammer | e3480d61f0 | |
Derrick Hammer | 8d5f0ba539 | |
Derrick Hammer | cfcedc3670 | |
Derrick Hammer | ffe01db460 | |
Derrick Hammer | b2b4d7b8ea | |
Derrick Hammer | 5381184a07 | |
Derrick Hammer | de5aa03ba3 | |
Derrick Hammer | 3c0510c272 | |
Derrick Hammer | 713430f00f | |
Derrick Hammer | cadd9e1d5c | |
Derrick Hammer | de4cb673cc | |
Derrick Hammer | 31505980c9 | |
Derrick Hammer | 5e68896eea | |
Derrick Hammer | 77e7f290d8 | |
Derrick Hammer | f8f8780f97 | |
Derrick Hammer | 3bc2dfadce | |
Derrick Hammer | 63e214cc49 | |
Derrick Hammer | 070b117089 | |
Derrick Hammer | 0f3de13f52 | |
Derrick Hammer | d18e3a9da5 | |
Derrick Hammer | 620e983011 | |
Derrick Hammer | 42751d5214 | |
Derrick Hammer | 6f1d761c99 | |
Derrick Hammer | 2d0c55848b | |
Derrick Hammer | 9a9283cc8a | |
Derrick Hammer | bc3550ab4b | |
Derrick Hammer | 9e7e0c7f65 | |
Derrick Hammer | 3e8aaa1dba | |
Derrick Hammer | cde0ea645f | |
Derrick Hammer | daf38957a4 | |
Derrick Hammer | d490ac55ce | |
Derrick Hammer | 13712d2501 | |
Derrick Hammer | d8dbc882a5 | |
Derrick Hammer | f51c4381b4 | |
Derrick Hammer | 3250edf166 | |
Derrick Hammer | 4797ea7be2 | |
Derrick Hammer | f287e0793f | |
Derrick Hammer | aa9ed84aea | |
Derrick Hammer | 5de87a9b3f |
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
|
||||
"changelog": "@changesets/cli/changelog",
|
||||
"commit": false,
|
||||
"fixed": [],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "master",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": []
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
# preset generated files
|
||||
/.eslintrc.json
|
||||
/.husky
|
||||
/.jestrc.json
|
||||
/.gitignore
|
||||
/.lintstagedrc.json
|
||||
/.npmignore
|
||||
/.prettierrc.json
|
||||
/tsconfig.json
|
||||
/tsconfig.build.json
|
||||
|
||||
# dependency
|
||||
node_modules
|
||||
# output
|
||||
/lib
|
||||
/generated
|
||||
# coverage
|
||||
/coverage
|
||||
*.lcov
|
||||
# diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
# log
|
||||
/log
|
||||
/logs
|
||||
*.log
|
||||
*-debug.log*
|
||||
.*-debug.log*
|
||||
# cache
|
||||
.DS_Store
|
||||
.cache
|
||||
.npm
|
||||
.pnpm*
|
||||
*.tsbuildinfo
|
||||
# configuration
|
||||
.env*
|
||||
!.env*.example
|
||||
src/account/generated
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"preset": [
|
||||
"presetter-preset-esm"
|
||||
],
|
||||
"config": {
|
||||
"prettier": {
|
||||
"singleQuote": false
|
||||
},
|
||||
"tsconfig.build": {
|
||||
"include": {
|
||||
"0": "src"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"rootDir": "src"
|
||||
}
|
||||
},
|
||||
"tsconfig": {
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"dom"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 LumeWeb
|
||||
Copyright (c) 2024 Hammer Technologies LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,18 @@
|
|||
import { defineConfig } from 'orval';
|
||||
|
||||
export default defineConfig({
|
||||
account: {
|
||||
input: './src/account/swagger.yaml',
|
||||
output: {
|
||||
mode: 'split',
|
||||
workspace: "./src/account/generated",
|
||||
target: 'openapi.ts',
|
||||
override: {
|
||||
mutator: {
|
||||
path: '../axios.ts',
|
||||
name: 'customInstance',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "@lumeweb/portal-sdk",
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"scripts": {
|
||||
"prepare": "presetter bootstrap",
|
||||
"build": "run build",
|
||||
"postinstall": "patch-package",
|
||||
"patch-package": "patch-package",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "gitea@git.lumeweb.com:LumeWeb/portal-sdk.git"
|
||||
},
|
||||
"private": false,
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.27.1",
|
||||
"presetter": "^4.7.0",
|
||||
"presetter-preset-esm": "^4.7.0"
|
||||
},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"_id": "@lumeweb/portal-sdk@0.0.0",
|
||||
"dependencies": {
|
||||
"@lumeweb/s5-js": "0.0.0-20240329003038",
|
||||
"axios": "^1.6.7",
|
||||
"memize": "^2.1.0",
|
||||
"orval": "^6.25.0",
|
||||
"patch-package": "^8.0.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
diff --git a/node_modules/tsc-alias/dist/utils/import-path-resolver.js b/node_modules/tsc-alias/dist/utils/import-path-resolver.js
|
||||
index ebaf620..227d4c7 100644
|
||||
--- a/node_modules/tsc-alias/dist/utils/import-path-resolver.js
|
||||
+++ b/node_modules/tsc-alias/dist/utils/import-path-resolver.js
|
||||
@@ -5,8 +5,9 @@ const normalizePath = require("normalize-path");
|
||||
const fs_1 = require("fs");
|
||||
const path_1 = require("path");
|
||||
const anyQuote = `["']`;
|
||||
+const excludeLocalImportSyntax = `[(?!\.)]`;
|
||||
const pathStringContent = `[^"'\r\n]+`;
|
||||
-const importString = `(?:${anyQuote}${pathStringContent}${anyQuote})`;
|
||||
+const importString = `(?:${anyQuote}${excludeLocalImportSyntax}${pathStringContent}${anyQuote})`;
|
||||
const funcStyle = `(?:\\b(?:import|require)\\s*\\(\\s*(\\/\\*.*\\*\\/\\s*)?${importString}\\s*\\))`;
|
||||
const globalStyle = `(?:\\bimport\\s+${importString})`;
|
||||
const fromStyle = `(?:\\bfrom\\s+${importString})`;
|
|
@ -0,0 +1,357 @@
|
|||
import {
|
||||
AccountInfoResponse,
|
||||
getApiAccount,
|
||||
LoginRequest,
|
||||
LoginResponse,
|
||||
OTPDisableRequest,
|
||||
OTPGenerateResponse,
|
||||
OTPValidateRequest,
|
||||
OTPVerifyRequest,
|
||||
PasswordResetVerifyRequest,
|
||||
PingResponse,
|
||||
postApiAccountPasswordResetRequest,
|
||||
postApiAccountVerifyEmailResend,
|
||||
postApiAuthPing,
|
||||
RegisterRequest,
|
||||
UploadLimitResponse,
|
||||
VerifyEmailRequest,
|
||||
} from "./account/generated/index.js";
|
||||
|
||||
import {
|
||||
postApiAuthLogin,
|
||||
postApiAuthRegister,
|
||||
postApiAccountVerifyEmail,
|
||||
getApiAuthOtpGenerate,
|
||||
postApiAccountOtpVerify,
|
||||
postApiAccountOtpValidate,
|
||||
postApiAuthOtpDisable,
|
||||
PasswordResetRequest,
|
||||
postApiAccountPasswordResetConfirm,
|
||||
postApiAuthLogout,
|
||||
getApiUploadLimit,
|
||||
postApiAccountUpdateEmail,
|
||||
postApiAccountUpdatePassword,
|
||||
} from "./account/generated/index.js";
|
||||
import { AxiosError, AxiosResponse } from "axios";
|
||||
|
||||
export class AccountError extends Error {
|
||||
public statusCode: number;
|
||||
|
||||
constructor(message: string, statusCode: number) {
|
||||
super(message);
|
||||
this.name = "AccountError";
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountApi {
|
||||
private apiUrl: string;
|
||||
private _jwtToken?: string;
|
||||
|
||||
constructor(apiUrl: string) {
|
||||
let apiUrlParsed = new URL(apiUrl);
|
||||
|
||||
apiUrlParsed.hostname = `account.${apiUrlParsed.hostname}`;
|
||||
this.apiUrl = apiUrlParsed.toString();
|
||||
}
|
||||
|
||||
set jwtToken(value: string) {
|
||||
this._jwtToken = value;
|
||||
}
|
||||
|
||||
get jwtToken(): string {
|
||||
return <string>this._jwtToken;
|
||||
}
|
||||
|
||||
public static create(apiUrl: string): AccountApi {
|
||||
return new AccountApi(apiUrl);
|
||||
}
|
||||
|
||||
public async login(
|
||||
loginRequest: LoginRequest,
|
||||
): Promise<boolean | AccountError> {
|
||||
let ret: AxiosResponse<LoginResponse> | LoginResponse | boolean = false;
|
||||
try {
|
||||
ret = await postApiAuthLogin(loginRequest, { baseURL: this.apiUrl });
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
ret = this.checkSuccessVal<LoginResponse>(ret);
|
||||
|
||||
if (ret) {
|
||||
this._jwtToken = (ret as LoginResponse).token;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async register(
|
||||
registerRequest: RegisterRequest,
|
||||
): Promise<boolean | Error> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAuthRegister(registerRequest, {
|
||||
baseURL: this.apiUrl,
|
||||
});
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
public async verifyEmail(
|
||||
verifyEmailRequest: VerifyEmailRequest,
|
||||
): Promise<boolean | Error> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAccountVerifyEmail(
|
||||
verifyEmailRequest,
|
||||
this.buildOptions(),
|
||||
);
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
public async requestEmailVerification(): Promise<boolean | AccountError> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAccountVerifyEmailResend(this.buildOptions());
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
public async generateOtp(): Promise<
|
||||
boolean | OTPGenerateResponse | AccountError
|
||||
> {
|
||||
let ret: AxiosResponse<OTPGenerateResponse>;
|
||||
try {
|
||||
ret = await getApiAuthOtpGenerate(this.buildOptions());
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
return this.checkSuccessVal<OTPGenerateResponse>(ret);
|
||||
}
|
||||
|
||||
public async verifyOtp(
|
||||
otpVerifyRequest: OTPVerifyRequest,
|
||||
): Promise<boolean | Error> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAccountOtpVerify(
|
||||
otpVerifyRequest,
|
||||
this.buildOptions(),
|
||||
);
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
public async validateOtp(
|
||||
otpValidateRequest: OTPValidateRequest,
|
||||
): Promise<boolean | AccountError> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAccountOtpValidate(
|
||||
otpValidateRequest,
|
||||
this.buildOptions(),
|
||||
);
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
public async disableOtp(
|
||||
otpDisableRequest: OTPDisableRequest,
|
||||
): Promise<boolean | AccountError> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAuthOtpDisable(otpDisableRequest, this.buildOptions());
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
public async requestPasswordReset(
|
||||
passwordResetRequest: PasswordResetRequest,
|
||||
): Promise<boolean | AccountError> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAccountPasswordResetRequest(
|
||||
passwordResetRequest,
|
||||
this.buildOptions(),
|
||||
);
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
public async confirmPasswordReset(
|
||||
passwordResetVerifyRequest: PasswordResetVerifyRequest,
|
||||
): Promise<boolean | AccountError> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAccountPasswordResetConfirm(
|
||||
passwordResetVerifyRequest,
|
||||
this.buildOptions(),
|
||||
);
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
public async ping(): Promise<boolean> {
|
||||
let ret: AxiosResponse<PingResponse>;
|
||||
try {
|
||||
ret = await postApiAuthPing(this.buildOptions());
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const success = this.checkSuccessVal(ret) && ret.data.ping == "pong";
|
||||
|
||||
if (success) {
|
||||
this._jwtToken = ret.data.token;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public async info(): Promise<boolean | AccountInfoResponse> {
|
||||
let ret: AxiosResponse<AccountInfoResponse>;
|
||||
try {
|
||||
ret = await getApiAccount(this.buildOptions());
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.checkSuccessVal(ret);
|
||||
}
|
||||
|
||||
public async logout(): Promise<boolean> {
|
||||
try {
|
||||
await postApiAuthLogout(this.buildOptions());
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._jwtToken = undefined;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async uploadLimit(): Promise<number> {
|
||||
let ret: AxiosResponse<UploadLimitResponse>;
|
||||
try {
|
||||
ret = await getApiUploadLimit(this.buildOptions());
|
||||
} catch (e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.checkSuccessVal<UploadLimitResponse>(ret) ? ret.data.limit : 0;
|
||||
}
|
||||
|
||||
public async updateEmail(
|
||||
email: string,
|
||||
password: string,
|
||||
): Promise<boolean | AccountError> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAccountUpdateEmail(
|
||||
{ email, password },
|
||||
this.buildOptions(),
|
||||
);
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
public async updatePassword(
|
||||
currentPassword: string,
|
||||
newPassword: string,
|
||||
): Promise<boolean | AccountError> {
|
||||
let ret: AxiosResponse<void>;
|
||||
try {
|
||||
ret = await postApiAccountUpdatePassword(
|
||||
{ current_password: currentPassword, new_password: newPassword },
|
||||
this.buildOptions(),
|
||||
);
|
||||
} catch (e) {
|
||||
return new AccountError(
|
||||
(e as AxiosError).response?.data as string,
|
||||
(e as AxiosError).response?.status as number,
|
||||
);
|
||||
}
|
||||
|
||||
return this.checkSuccessBool(ret);
|
||||
}
|
||||
|
||||
private checkSuccessBool(ret: AxiosResponse<void>): boolean {
|
||||
return ret.status === 200;
|
||||
}
|
||||
|
||||
private checkSuccessVal<T>(ret: AxiosResponse<T>): T | boolean {
|
||||
if (ret.status === 200) {
|
||||
return ret.data as T;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private buildOptions(): any {
|
||||
const headers: any = {};
|
||||
if (this.jwtToken) {
|
||||
headers.Authorization = `Bearer ${this.jwtToken}`;
|
||||
}
|
||||
|
||||
return {
|
||||
baseURL: this.apiUrl,
|
||||
headers: headers,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import Axios, { AxiosRequestConfig, AxiosResponse } from "axios";
|
||||
import memize from "memize";
|
||||
|
||||
const axiosCreate = memize(Axios.create);
|
||||
|
||||
export const customInstance = <T>(
|
||||
config: AxiosRequestConfig,
|
||||
options?: AxiosRequestConfig,
|
||||
): Promise<AxiosResponse<T>> => {
|
||||
const source = Axios.CancelToken.source();
|
||||
|
||||
const instance = axiosCreate({ baseURL: options?.baseURL });
|
||||
const promise = instance({
|
||||
...config,
|
||||
...options,
|
||||
cancelToken: source.token,
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
promise.cancel = () => {
|
||||
source.cancel("Query was cancelled");
|
||||
};
|
||||
|
||||
return promise;
|
||||
};
|
|
@ -0,0 +1,350 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Account Management API
|
||||
version: "1.0"
|
||||
description: API for managing user accounts, including login, registration, OTP operations, and password resets.
|
||||
paths:
|
||||
/api/auth/login:
|
||||
post:
|
||||
summary: Login to the system
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/LoginRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully logged in
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/LoginResponse"
|
||||
"401":
|
||||
description: Unauthorized
|
||||
/api/auth/logout:
|
||||
post:
|
||||
summary: Logout of account service
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully logged out
|
||||
/api/auth/register:
|
||||
post:
|
||||
summary: Register a new account
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/RegisterRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully registered
|
||||
"400":
|
||||
description: Bad Request
|
||||
/api/account/verify-email:
|
||||
post:
|
||||
summary: Verify email address
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/VerifyEmailRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Email verified successfully
|
||||
/api/account/verify-email/resend:
|
||||
post:
|
||||
summary: Resend email verification
|
||||
responses:
|
||||
"200":
|
||||
description: Email verification resent successfully
|
||||
/api/auth/otp/generate:
|
||||
get:
|
||||
summary: Generate OTP for two-factor authentication
|
||||
responses:
|
||||
"200":
|
||||
description: OTP generated successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/OTPGenerateResponse"
|
||||
/api/account/otp/verify:
|
||||
post:
|
||||
summary: Verify OTP for enabling two-factor authentication
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/OTPVerifyRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: OTP verified successfully
|
||||
/api/account/otp/validate:
|
||||
post:
|
||||
summary: Validate OTP for two-factor authentication login
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/OTPValidateRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: OTP validated successfully
|
||||
/api/auth/otp/disable:
|
||||
post:
|
||||
summary: Disable OTP for two-factor authentication
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/OTPDisableRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: OTP disabled successfully
|
||||
/api/account/password-reset/request:
|
||||
post:
|
||||
summary: Request a password reset
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PasswordResetRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Password reset requested successfully
|
||||
/api/account/password-reset/confirm:
|
||||
post:
|
||||
summary: Confirm a password reset
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PasswordResetVerifyRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Password reset successfully
|
||||
/api/auth/ping:
|
||||
post:
|
||||
summary: Auth check endpoint
|
||||
responses:
|
||||
"200":
|
||||
description: Pong
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PingResponse"
|
||||
"401":
|
||||
description: Unauthorized
|
||||
/api/account:
|
||||
get:
|
||||
summary: Get account information
|
||||
responses:
|
||||
"200":
|
||||
description: Account information retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/AccountInfoResponse"
|
||||
"401":
|
||||
description: Unauthorized
|
||||
/api/account/update-email:
|
||||
post:
|
||||
summary: Update email address
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UpdateEmailRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Email updated successfully
|
||||
/api/account/update-password:
|
||||
post:
|
||||
summary: Update password
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UpdatePasswordRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Password updated successfully
|
||||
/api/upload-limit:
|
||||
get:
|
||||
summary: Get the basic file upload (POST) upload limit set by the portal
|
||||
responses:
|
||||
"200":
|
||||
description: Upload limit retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UploadLimitResponse"
|
||||
/api/meta:
|
||||
get:
|
||||
summary: Get metadata about the portal
|
||||
responses:
|
||||
"200":
|
||||
description: Metadata retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/MetaResponse"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
LoginRequest:
|
||||
type: object
|
||||
required:
|
||||
- email
|
||||
- password
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
LoginResponse:
|
||||
type: object
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
RegisterRequest:
|
||||
type: object
|
||||
required:
|
||||
- first_name
|
||||
- last_name
|
||||
- email
|
||||
- password
|
||||
properties:
|
||||
first_name:
|
||||
type: string
|
||||
last_name:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
VerifyEmailRequest:
|
||||
type: object
|
||||
required:
|
||||
- email
|
||||
- token
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
token:
|
||||
type: string
|
||||
OTPGenerateResponse:
|
||||
type: object
|
||||
properties:
|
||||
OTP:
|
||||
type: string
|
||||
OTPVerifyRequest:
|
||||
type: object
|
||||
required:
|
||||
- OTP
|
||||
properties:
|
||||
OTP:
|
||||
type: string
|
||||
OTPValidateRequest:
|
||||
type: object
|
||||
required:
|
||||
- OTP
|
||||
properties:
|
||||
OTP:
|
||||
type: string
|
||||
OTPDisableRequest:
|
||||
type: object
|
||||
required:
|
||||
- password
|
||||
properties:
|
||||
password:
|
||||
type: string
|
||||
PasswordResetRequest:
|
||||
type: object
|
||||
required:
|
||||
- email
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
PasswordResetVerifyRequest:
|
||||
type: object
|
||||
required:
|
||||
- email
|
||||
- token
|
||||
- password
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
token:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
UpdateEmailRequest:
|
||||
type: object
|
||||
required:
|
||||
- email
|
||||
- password
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
UpdatePasswordRequest:
|
||||
type: object
|
||||
required:
|
||||
- current_password
|
||||
- new_password
|
||||
properties:
|
||||
current_password:
|
||||
type: string
|
||||
new_password:
|
||||
type: string
|
||||
PingResponse:
|
||||
type: object
|
||||
properties:
|
||||
ping:
|
||||
type: string
|
||||
token:
|
||||
type: string
|
||||
AccountInfoResponse:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- first_name
|
||||
- last_name
|
||||
- email
|
||||
- verified
|
||||
properties:
|
||||
id:
|
||||
type: number
|
||||
first_name:
|
||||
type: string
|
||||
last_name:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
verified:
|
||||
type: boolean
|
||||
UploadLimitResponse:
|
||||
type: object
|
||||
properties:
|
||||
limit:
|
||||
type: number
|
||||
required:
|
||||
- limit
|
||||
MetaResponse:
|
||||
type: object
|
||||
required:
|
||||
- domain
|
||||
properties:
|
||||
domain:
|
||||
type: string
|
|
@ -0,0 +1,4 @@
|
|||
export * from "./sdk.js";
|
||||
export * from "./account/generated/openapi.schemas.js";
|
||||
export * from "./protocol/index.js";
|
||||
export { AccountError } from "./account.js";
|
|
@ -0,0 +1,24 @@
|
|||
export abstract class Protocol<T> {
|
||||
private sdk: T;
|
||||
|
||||
constructor(sdk: T) {
|
||||
this.sdk = sdk;
|
||||
}
|
||||
|
||||
public getSdk(): T {
|
||||
return this.sdk;
|
||||
}
|
||||
|
||||
public abstract setAuthToken(token: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ProtocolConstructor<T> {
|
||||
new (apiDomain: string): Protocol<T>;
|
||||
}
|
||||
|
||||
export function createProtocol<T>(
|
||||
implementation: ProtocolConstructor<T>,
|
||||
apiDomain: string,
|
||||
): Protocol<T> {
|
||||
return new implementation(apiDomain);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import { Protocol } from "./protocol";
|
||||
import { S5Client } from "@lumeweb/s5-js";
|
||||
|
||||
export const PROTOCOL_S5 = "s5";
|
||||
|
||||
export class S5 extends Protocol<S5Client> {
|
||||
constructor(apiDomain: string) {
|
||||
const sdk = new S5Client(`s5.${apiDomain}`);
|
||||
|
||||
super(sdk);
|
||||
}
|
||||
|
||||
async setAuthToken(token: string): Promise<void> {
|
||||
const options = this.getSdk().clientOptions;
|
||||
options.apiKey = token;
|
||||
this.getSdk().clientOptions = options;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { Registry } from "./registry";
|
||||
import { createProtocol, Protocol } from "./impl/protocol.js";
|
||||
import { S5Client } from "@lumeweb/s5-js";
|
||||
import { PROTOCOL_S5, S5 } from "./impl/s5.js";
|
||||
|
||||
export function registerDefaults(registry: Registry) {
|
||||
registry.register<S5Client>(
|
||||
PROTOCOL_S5,
|
||||
createProtocol<S5Client>(S5, registry.getApiDomain()),
|
||||
);
|
||||
}
|
||||
|
||||
export { Protocol, Registry };
|
||||
export { PROTOCOL_S5 };
|
|
@ -0,0 +1,34 @@
|
|||
import { Sdk } from "../sdk";
|
||||
import { Protocol } from "./impl/protocol";
|
||||
|
||||
export class Registry {
|
||||
private store: Map<string, Protocol<any>>;
|
||||
private sdk: Sdk;
|
||||
private _apiDomain?: string;
|
||||
|
||||
constructor(sdk: Sdk) {
|
||||
this.store = new Map();
|
||||
this.sdk = sdk;
|
||||
}
|
||||
|
||||
public register<T>(name: string, value: Protocol<T>) {
|
||||
this.store.set(name, value);
|
||||
}
|
||||
|
||||
public get<T>(name: string): Protocol<T> {
|
||||
return this.store.get(name) as Protocol<T>;
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.store[Symbol.iterator]();
|
||||
}
|
||||
|
||||
public getApiDomain(): string {
|
||||
if (!this._apiDomain) {
|
||||
const urlObject = new URL(this.sdk.apiUrl);
|
||||
this._apiDomain = urlObject.hostname;
|
||||
}
|
||||
|
||||
return this._apiDomain;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import { AccountApi } from "./account.js";
|
||||
import { registerDefaults, Registry } from "./protocol/index.js";
|
||||
|
||||
export class Sdk {
|
||||
private accountApi?: AccountApi;
|
||||
private registry?: Registry;
|
||||
|
||||
constructor(apiUrl: string) {
|
||||
this._apiUrl = apiUrl;
|
||||
}
|
||||
|
||||
private _apiUrl: string;
|
||||
|
||||
get apiUrl(): string {
|
||||
return this._apiUrl;
|
||||
}
|
||||
|
||||
set apiUrl(value: string) {
|
||||
this._apiUrl = value;
|
||||
}
|
||||
|
||||
public static create(apiUrl: string): Sdk {
|
||||
return new Sdk(apiUrl);
|
||||
}
|
||||
|
||||
public account(): AccountApi {
|
||||
if (!this.accountApi) {
|
||||
this.accountApi = AccountApi.create(this._apiUrl);
|
||||
}
|
||||
return this.accountApi!;
|
||||
}
|
||||
|
||||
public protocols(): Registry {
|
||||
if (!this.registry) {
|
||||
this.registry = new Registry(this);
|
||||
registerDefaults(this.registry!);
|
||||
}
|
||||
|
||||
return this.registry!;
|
||||
}
|
||||
|
||||
public setAuthToken(token: string) {
|
||||
this.account().jwtToken = token;
|
||||
|
||||
for (const [, protocol] of this.protocols()) {
|
||||
protocol.setAuthToken(token);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue