mirror of
https://github.com/lucaspalomodevelop/auth-tools.git
synced 2026-03-12 22:07:22 +00:00
Merge pull request #6 from auth-tools/dev/2-client
Merge `dev/2-client` into `develop`
This commit is contained in:
commit
ab0cb85957
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth-tools/base",
|
||||
"version": "0.0.1-alpha.2",
|
||||
"version": "0.0.1-alpha.8",
|
||||
"description": "A structured authentication protocol for Javascript. (base)",
|
||||
"main": "dist/index.js",
|
||||
"repository": "https://github.com/auth-tools/auth-tools",
|
||||
|
||||
@ -14,7 +14,7 @@ export type InterceptEventsDefinition = {
|
||||
type InterceptEvent<ClassInterceptEvents extends InterceptEventDefinition> = {
|
||||
data: ClassInterceptEvents["data"];
|
||||
return: {
|
||||
serverError?: boolean;
|
||||
error?: boolean;
|
||||
intercepted: boolean;
|
||||
interceptCode: number;
|
||||
};
|
||||
|
||||
@ -14,7 +14,7 @@ export type UseEventsDefinition = {
|
||||
//data for an use event
|
||||
type UseEvent<ClassUseEvents extends UseEventDefinition> = {
|
||||
data: ClassUseEvents["data"];
|
||||
return: { serverError?: boolean } & ClassUseEvents["return"];
|
||||
return: { error?: boolean } & ClassUseEvents["return"];
|
||||
};
|
||||
|
||||
//all use events
|
||||
|
||||
@ -19,14 +19,13 @@ type AuthResponseBuilder<
|
||||
InterceptCode extends number = 0,
|
||||
AuthMessage = AuthMessages[`${Method}_${StatusCode}`]
|
||||
> = {
|
||||
auth: {
|
||||
error: StatusCode extends 0 ? false : true;
|
||||
errorType: Method extends "server" ? "server" : "method";
|
||||
message: AuthMessage;
|
||||
codes: {
|
||||
status: StatusCode;
|
||||
intercept: InterceptCode;
|
||||
};
|
||||
error: StatusCode extends 0 ? false : true;
|
||||
intercepted: InterceptCode extends 0 ? false : true,
|
||||
errorType: Method extends "server" ? "server" : "method";
|
||||
message: AuthMessage;
|
||||
codes: {
|
||||
status: StatusCode;
|
||||
intercept: InterceptCode;
|
||||
};
|
||||
data: ResponseData;
|
||||
};
|
||||
@ -84,7 +83,6 @@ export type AuthProtocol = {
|
||||
validate_1: AuthResponseBuilder<"validate", 1, null>;
|
||||
validate_2: AuthResponseBuilder<"validate", 2, null>;
|
||||
validate_3: AuthResponseBuilder<"validate", 3, null>;
|
||||
validate_9: AuthResponseBuilder<"validate", 9, null, number>;
|
||||
}
|
||||
>;
|
||||
register: AuthMethodBuilder<
|
||||
|
||||
@ -5,7 +5,6 @@ export type AuthMessages = {
|
||||
validate_1: "The validation method is disabled.";
|
||||
validate_2: 'The "accessToken" is missing.';
|
||||
validate_3: 'The "accessToken" is invalid.';
|
||||
validate_9: "The validation request was intercepted.";
|
||||
register_0: "Registration successful.";
|
||||
register_1: "The registration method is disabled.";
|
||||
register_2: 'The "email", "username" or "password" is missing.';
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth-tools/client",
|
||||
"version": "0.0.0",
|
||||
"version": "0.0.1-alpha.4",
|
||||
"description": "A structured authentication protocol for Javascript. (client)",
|
||||
"main": "dist/index.js",
|
||||
"repository": "https://github.com/auth-tools/auth-tools",
|
||||
@ -14,9 +14,12 @@
|
||||
"prepublish": "npm run build",
|
||||
"remove": "npm run build:remove && rimraf node_modules yarn.lock package-lock.json pnpm-lock.yaml"
|
||||
},
|
||||
"dependencies": {},
|
||||
"dependencies": {
|
||||
"@auth-tools/base": "^0.0.1-alpha.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@auth-tools/client": "link:.",
|
||||
"@auth-tools/logger": "^0.0.1-alpha.1",
|
||||
"rimraf": "^5.0.5",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"typescript": "^5.4.5"
|
||||
|
||||
93
packages/client/src/auth.ts
Normal file
93
packages/client/src/auth.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import {
|
||||
AuthBase,
|
||||
AuthProtocol,
|
||||
AuthRequest,
|
||||
AuthResponse,
|
||||
Promisify,
|
||||
UseEventCallbacks,
|
||||
User,
|
||||
} from "@auth-tools/base";
|
||||
import { LogFunction } from "@auth-tools/logger";
|
||||
import { undefinedUseEvent } from "./events";
|
||||
import { createValidate } from "./methods/validate";
|
||||
import { createRegister } from "./methods/register";
|
||||
import { createLogin } from "./methods/login";
|
||||
import { createLogout } from "./methods/logout";
|
||||
import { createRefresh } from "./methods/refresh";
|
||||
import { createCheck } from "./methods/check";
|
||||
|
||||
type MethodReturn<MethodName extends keyof AuthProtocol> =
|
||||
| { clientError: true; res: null }
|
||||
| { clientError: false; res: AuthResponse<MethodName> };
|
||||
|
||||
export type AuthClientConnector<MethodName extends keyof AuthProtocol> = (
|
||||
method: MethodName,
|
||||
data: AuthRequest<MethodName>
|
||||
) => Promisify<MethodReturn<MethodName>>;
|
||||
|
||||
type TokenTypes = "accessToken" | "refreshToken";
|
||||
|
||||
//config passed by user to class
|
||||
export type AuthClientConfig = {
|
||||
connector: AuthClientConnector<keyof AuthProtocol>;
|
||||
};
|
||||
|
||||
//all use events
|
||||
export type AuthClientUseEvents = {
|
||||
getToken: {
|
||||
data: { type: TokenTypes };
|
||||
return: { token: User<TokenTypes>[TokenTypes] | null };
|
||||
};
|
||||
storeToken: {
|
||||
data: { type: TokenTypes; token: User<TokenTypes>[TokenTypes] };
|
||||
return: {};
|
||||
};
|
||||
deleteToken: {
|
||||
data: { type: TokenTypes };
|
||||
return: {};
|
||||
};
|
||||
};
|
||||
|
||||
export type AuthClientMethod<
|
||||
MethodName extends keyof AuthProtocol,
|
||||
NoData extends boolean = MethodName extends "logout" | "refresh" | "check"
|
||||
? true
|
||||
: false
|
||||
> = (
|
||||
data: NoData extends true ? {} : AuthRequest<MethodName>
|
||||
) => Promise<MethodReturn<MethodName>>;
|
||||
|
||||
type AuthClientMethods = {
|
||||
[MethodName in keyof AuthProtocol]: AuthClientMethod<MethodName>;
|
||||
};
|
||||
|
||||
export class AuthClient extends AuthBase<
|
||||
AuthClientConfig,
|
||||
AuthClientUseEvents,
|
||||
{}
|
||||
> {
|
||||
//all methods
|
||||
public methods: AuthClientMethods;
|
||||
|
||||
constructor(config: AuthClientConfig, log: LogFunction) {
|
||||
//defaults for use event callbacks
|
||||
const defaultedUseEvents: UseEventCallbacks<AuthClientUseEvents> = {
|
||||
getToken: undefinedUseEvent("getToken", { token: "" }, log),
|
||||
storeToken: undefinedUseEvent("storeToken", {}, log),
|
||||
deleteToken: undefinedUseEvent("deleteToken", {}, log),
|
||||
};
|
||||
|
||||
//init authbase class
|
||||
super(config, log, defaultedUseEvents, {});
|
||||
|
||||
//all auth methods
|
||||
this.methods = {
|
||||
validate: createValidate(this._internal),
|
||||
register: createRegister(this._internal),
|
||||
login: createLogin(this._internal),
|
||||
logout: createLogout(this._internal),
|
||||
refresh: createRefresh(this._internal),
|
||||
check: createCheck(this._internal),
|
||||
};
|
||||
}
|
||||
}
|
||||
19
packages/client/src/events.ts
Normal file
19
packages/client/src/events.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { UseEventCallbacks } from "@auth-tools/base";
|
||||
import { AuthClientUseEvents } from "./auth";
|
||||
import { LogFunction } from "@auth-tools/logger";
|
||||
|
||||
//for an undefined use event
|
||||
export function undefinedUseEvent<
|
||||
Event extends keyof AuthClientUseEvents,
|
||||
Return extends AuthClientUseEvents[Event]["return"]
|
||||
>(
|
||||
event: Event,
|
||||
returnData: Return,
|
||||
log: LogFunction
|
||||
): UseEventCallbacks<AuthClientUseEvents>[Event] {
|
||||
return (() => {
|
||||
//complain about unset use event callback
|
||||
log("error", `The use "${event}" event is not defined!`);
|
||||
return { ...returnData, error: true };
|
||||
}) as UseEventCallbacks<AuthClientUseEvents>[Event];
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
export { AuthClient as default } from "./auth";
|
||||
export {
|
||||
AuthClient,
|
||||
AuthClientConfig,
|
||||
AuthClientConnector,
|
||||
AuthClientMethod,
|
||||
} from "./auth";
|
||||
13
packages/client/src/methods/_template.ts.txt
Normal file
13
packages/client/src/methods/_template.ts.txt
Normal file
@ -0,0 +1,13 @@
|
||||
import { AuthInternal } from "@auth-tools/base";
|
||||
import {
|
||||
AuthClientConfig,
|
||||
AuthClientMethod,
|
||||
AuthClientUseEvents,
|
||||
} from "../auth";
|
||||
|
||||
//create _method method
|
||||
export function create_Method(
|
||||
internal: AuthInternal<AuthClientConfig, AuthClientUseEvents, {}>
|
||||
): AuthClientMethod<"_method"> {
|
||||
return async ({}) => {};
|
||||
}
|
||||
37
packages/client/src/methods/check.ts
Normal file
37
packages/client/src/methods/check.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { AuthInternal } from "@auth-tools/base";
|
||||
import {
|
||||
AuthClientConfig,
|
||||
AuthClientConnector,
|
||||
AuthClientMethod,
|
||||
AuthClientUseEvents,
|
||||
} from "../auth";
|
||||
|
||||
//create check method
|
||||
export function createCheck(
|
||||
internal: AuthInternal<AuthClientConfig, AuthClientUseEvents, {}>
|
||||
): AuthClientMethod<"check"> {
|
||||
return async () => {
|
||||
const getRefreshToken = await internal.useEventCallbacks.getToken({
|
||||
type: "refreshToken",
|
||||
});
|
||||
|
||||
if (getRefreshToken.error || getRefreshToken.token === null)
|
||||
return { clientError: true, res: null };
|
||||
|
||||
const getAccessToken = await internal.useEventCallbacks.getToken({
|
||||
type: "accessToken",
|
||||
});
|
||||
|
||||
if (getAccessToken.error || getAccessToken.token === null)
|
||||
return { clientError: true, res: null };
|
||||
|
||||
const checkResponse = await (
|
||||
internal.config.connector as AuthClientConnector<"check">
|
||||
)("check", {
|
||||
accessToken: getAccessToken.token,
|
||||
refreshToken: getRefreshToken.token,
|
||||
});
|
||||
|
||||
return checkResponse;
|
||||
};
|
||||
}
|
||||
33
packages/client/src/methods/login.ts
Normal file
33
packages/client/src/methods/login.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { AuthInternal } from "@auth-tools/base";
|
||||
import {
|
||||
AuthClientConfig,
|
||||
AuthClientConnector,
|
||||
AuthClientMethod,
|
||||
AuthClientUseEvents,
|
||||
} from "../auth";
|
||||
|
||||
//create login method
|
||||
export function createLogin(
|
||||
internal: AuthInternal<AuthClientConfig, AuthClientUseEvents, {}>
|
||||
): AuthClientMethod<"login"> {
|
||||
return async ({ login, password }) => {
|
||||
const loginResponse = await (
|
||||
internal.config.connector as AuthClientConnector<"login">
|
||||
)("login", { login, password });
|
||||
|
||||
if (loginResponse.clientError || loginResponse.res.error)
|
||||
return loginResponse;
|
||||
|
||||
//store tokens
|
||||
internal.useEventCallbacks.storeToken({
|
||||
type: "accessToken",
|
||||
token: loginResponse.res.data.accessToken,
|
||||
});
|
||||
internal.useEventCallbacks.storeToken({
|
||||
type: "refreshToken",
|
||||
token: loginResponse.res.data.refreshToken,
|
||||
});
|
||||
|
||||
return loginResponse;
|
||||
};
|
||||
}
|
||||
36
packages/client/src/methods/logout.ts
Normal file
36
packages/client/src/methods/logout.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { AuthInternal } from "@auth-tools/base";
|
||||
import {
|
||||
AuthClientConfig,
|
||||
AuthClientConnector,
|
||||
AuthClientMethod,
|
||||
AuthClientUseEvents,
|
||||
} from "../auth";
|
||||
|
||||
//create logout method
|
||||
export function createLogout(
|
||||
internal: AuthInternal<AuthClientConfig, AuthClientUseEvents, {}>
|
||||
): AuthClientMethod<"logout"> {
|
||||
return async () => {
|
||||
const getRefreshToken = await internal.useEventCallbacks.getToken({
|
||||
type: "refreshToken",
|
||||
});
|
||||
|
||||
if (getRefreshToken.error || getRefreshToken.token === null)
|
||||
return { clientError: true, res: null };
|
||||
|
||||
const logoutResponse = await (
|
||||
internal.config.connector as AuthClientConnector<"logout">
|
||||
)("logout", { refreshToken: getRefreshToken.token });
|
||||
|
||||
if (!logoutResponse.clientError && !logoutResponse.res.error) {
|
||||
internal.useEventCallbacks.deleteToken({
|
||||
type: "accessToken",
|
||||
});
|
||||
internal.useEventCallbacks.deleteToken({
|
||||
type: "refreshToken",
|
||||
});
|
||||
}
|
||||
|
||||
return logoutResponse;
|
||||
};
|
||||
}
|
||||
34
packages/client/src/methods/refresh.ts
Normal file
34
packages/client/src/methods/refresh.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { AuthInternal } from "@auth-tools/base";
|
||||
import {
|
||||
AuthClientConfig,
|
||||
AuthClientConnector,
|
||||
AuthClientMethod,
|
||||
AuthClientUseEvents,
|
||||
} from "../auth";
|
||||
|
||||
//create refresh method
|
||||
export function createRefresh(
|
||||
internal: AuthInternal<AuthClientConfig, AuthClientUseEvents, {}>
|
||||
): AuthClientMethod<"refresh"> {
|
||||
return async () => {
|
||||
const getRefreshToken = await internal.useEventCallbacks.getToken({
|
||||
type: "refreshToken",
|
||||
});
|
||||
|
||||
if (getRefreshToken.error || getRefreshToken.token === null)
|
||||
return { clientError: true, res: null };
|
||||
|
||||
const refreshResponse = await (
|
||||
internal.config.connector as AuthClientConnector<"refresh">
|
||||
)("refresh", { refreshToken: getRefreshToken.token });
|
||||
|
||||
if (!refreshResponse.clientError && !refreshResponse.res.error) {
|
||||
internal.useEventCallbacks.storeToken({
|
||||
type: "accessToken",
|
||||
token: refreshResponse.res.data.accessToken,
|
||||
});
|
||||
}
|
||||
|
||||
return refreshResponse;
|
||||
};
|
||||
}
|
||||
20
packages/client/src/methods/register.ts
Normal file
20
packages/client/src/methods/register.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { AuthInternal } from "@auth-tools/base";
|
||||
import {
|
||||
AuthClientConfig,
|
||||
AuthClientConnector,
|
||||
AuthClientMethod,
|
||||
AuthClientUseEvents,
|
||||
} from "../auth";
|
||||
|
||||
//create register method
|
||||
export function createRegister(
|
||||
internal: AuthInternal<AuthClientConfig, AuthClientUseEvents, {}>
|
||||
): AuthClientMethod<"register"> {
|
||||
return async ({ email, username, password }) => {
|
||||
const registerResponse = await (
|
||||
internal.config.connector as AuthClientConnector<"register">
|
||||
)("register", { email, username, password });
|
||||
|
||||
return registerResponse;
|
||||
};
|
||||
}
|
||||
20
packages/client/src/methods/validate.ts
Normal file
20
packages/client/src/methods/validate.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { AuthInternal } from "@auth-tools/base";
|
||||
import {
|
||||
AuthClientConfig,
|
||||
AuthClientConnector,
|
||||
AuthClientMethod,
|
||||
AuthClientUseEvents,
|
||||
} from "../auth";
|
||||
|
||||
//create validate method
|
||||
export function createValidate(
|
||||
internal: AuthInternal<AuthClientConfig, AuthClientUseEvents, {}>
|
||||
): AuthClientMethod<"validate"> {
|
||||
return async ({ accessToken }) => {
|
||||
const validateResponse = await (
|
||||
internal.config.connector as AuthClientConnector<"validate">
|
||||
)("validate", { accessToken });
|
||||
|
||||
return validateResponse;
|
||||
};
|
||||
}
|
||||
21
packages/express/LICENSE
Normal file
21
packages/express/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 @auth-tools
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
0
packages/express/local/index.ts
Normal file
0
packages/express/local/index.ts
Normal file
32
packages/express/package.json
Normal file
32
packages/express/package.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@auth-tools/express",
|
||||
"version": "0.0.1-alpha.4",
|
||||
"description": "A structured authentication protocol for Javascript. (express)",
|
||||
"main": "dist/index.js",
|
||||
"repository": "https://github.com/auth-tools/auth-tools",
|
||||
"author": "Laurenz Rausche <laurenz@laurenz-rausche.de>",
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"build": "npm run build:remove && tsc",
|
||||
"build:remove": "rimraf dist",
|
||||
"local": "npm run build && ts-node-dev --respawn local/index.ts",
|
||||
"prepublish": "npm run build",
|
||||
"remove": "npm run build:remove && rimraf node_modules yarn.lock package-lock.json pnpm-lock.yaml"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.19.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@auth-tools/server": "^0.0.1-alpha.7",
|
||||
"@auth-tools/express": "link:.",
|
||||
"@types/express": "^4.17.21",
|
||||
"rimraf": "^5.0.5",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"peerDependencies": {},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
47
packages/express/src/express.ts
Normal file
47
packages/express/src/express.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { AuthServer } from "@auth-tools/server";
|
||||
import { RequestHandler, Router } from "express";
|
||||
import { register } from "./routes/register";
|
||||
import { login } from "./routes/login";
|
||||
import { logout } from "./routes/logout";
|
||||
import { refresh } from "./routes/refresh";
|
||||
import { check } from "./routes/check";
|
||||
import { validate } from "./middleWares/validate";
|
||||
|
||||
export function authExpress(authServer: AuthServer): {
|
||||
middleWare: { validate?: RequestHandler };
|
||||
router: Router;
|
||||
} {
|
||||
//create router
|
||||
const router = Router();
|
||||
|
||||
//add routes
|
||||
if (authServer._internal.config.methods.register !== "removed") {
|
||||
router.post("/register", register(authServer));
|
||||
}
|
||||
|
||||
if (authServer._internal.config.methods.login !== "removed") {
|
||||
router.post("/login", login(authServer));
|
||||
}
|
||||
|
||||
if (authServer._internal.config.methods.logout !== "removed") {
|
||||
router.post("/logout", logout(authServer));
|
||||
}
|
||||
|
||||
if (authServer._internal.config.methods.refresh !== "removed") {
|
||||
router.post("/refresh", refresh(authServer));
|
||||
}
|
||||
|
||||
if (authServer._internal.config.methods.check !== "removed") {
|
||||
router.post("/check", check(authServer));
|
||||
}
|
||||
|
||||
return {
|
||||
middleWare: {
|
||||
validate:
|
||||
authServer._internal.config.methods.validate !== "removed"
|
||||
? undefined
|
||||
: validate(authServer),
|
||||
},
|
||||
router,
|
||||
};
|
||||
}
|
||||
2
packages/express/src/index.ts
Normal file
2
packages/express/src/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { authExpress as default } from "./express";
|
||||
export { authExpress } from "./express";
|
||||
28
packages/express/src/middleWares/validate.ts
Normal file
28
packages/express/src/middleWares/validate.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import AuthServer, { AuthServerMethod } from "@auth-tools/server";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
const HTTP_CODES = {
|
||||
1: 403,
|
||||
2: 400,
|
||||
3: 403,
|
||||
5: 500,
|
||||
};
|
||||
|
||||
export function validate(authServer: AuthServer): RequestHandler {
|
||||
return async (req, res, next) => {
|
||||
const authHeader = req.get("authorization");
|
||||
const accessToken = authHeader && authHeader.split(" ")[1];
|
||||
|
||||
const response = await (
|
||||
authServer.methods.validate as AuthServerMethod<"validate">
|
||||
)({ accessToken });
|
||||
|
||||
if (response.error) {
|
||||
return res.status(HTTP_CODES[response.codes.status]).json(response);
|
||||
}
|
||||
|
||||
res.locals.payload = { id: response.data.id };
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
25
packages/express/src/routes/check.ts
Normal file
25
packages/express/src/routes/check.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import AuthServer, { AuthServerMethod } from "@auth-tools/server";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
const HTTP_CODES = {
|
||||
0: 200,
|
||||
1: 403,
|
||||
2: 400,
|
||||
3: 403,
|
||||
4: 404,
|
||||
5: 403,
|
||||
9: 403,
|
||||
};
|
||||
|
||||
export function check(authServer: AuthServer): RequestHandler {
|
||||
return async (req, res) => {
|
||||
const response = await (
|
||||
authServer.methods.check as AuthServerMethod<"check">
|
||||
)(req.body);
|
||||
|
||||
const httpCodes =
|
||||
response.errorType === "server" ? 500 : HTTP_CODES[response.codes.status];
|
||||
|
||||
res.status(httpCodes).json(response);
|
||||
};
|
||||
}
|
||||
25
packages/express/src/routes/login.ts
Normal file
25
packages/express/src/routes/login.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import AuthServer, { AuthServerMethod } from "@auth-tools/server";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
const HTTP_CODES = {
|
||||
0: 201,
|
||||
1: 403,
|
||||
2: 400,
|
||||
3: 404,
|
||||
4: 403,
|
||||
5: 403,
|
||||
9: 403,
|
||||
};
|
||||
|
||||
export function login(authServer: AuthServer): RequestHandler {
|
||||
return async (req, res) => {
|
||||
const response = await (
|
||||
authServer.methods.login as AuthServerMethod<"login">
|
||||
)(req.body);
|
||||
|
||||
const httpCodes =
|
||||
response.errorType === "server" ? 500 : HTTP_CODES[response.codes.status];
|
||||
|
||||
res.status(httpCodes).json(response);
|
||||
};
|
||||
}
|
||||
24
packages/express/src/routes/logout.ts
Normal file
24
packages/express/src/routes/logout.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import AuthServer, { AuthServerMethod } from "@auth-tools/server";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
const HTTP_CODES = {
|
||||
0: 200,
|
||||
1: 403,
|
||||
2: 400,
|
||||
3: 403,
|
||||
4: 404,
|
||||
9: 403,
|
||||
};
|
||||
|
||||
export function logout(authServer: AuthServer): RequestHandler {
|
||||
return async (req, res) => {
|
||||
const response = await (
|
||||
authServer.methods.logout as AuthServerMethod<"logout">
|
||||
)(req.body);
|
||||
|
||||
const httpCodes =
|
||||
response.errorType === "server" ? 500 : HTTP_CODES[response.codes.status];
|
||||
|
||||
res.status(httpCodes).json(response);
|
||||
};
|
||||
}
|
||||
24
packages/express/src/routes/refresh.ts
Normal file
24
packages/express/src/routes/refresh.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import AuthServer, { AuthServerMethod } from "@auth-tools/server";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
const HTTP_CODES = {
|
||||
0: 200,
|
||||
1: 403,
|
||||
2: 400,
|
||||
3: 403,
|
||||
4: 404,
|
||||
9: 403,
|
||||
};
|
||||
|
||||
export function refresh(authServer: AuthServer): RequestHandler {
|
||||
return async (req, res) => {
|
||||
const response = await (
|
||||
authServer.methods.refresh as AuthServerMethod<"refresh">
|
||||
)(req.body);
|
||||
|
||||
const httpCodes =
|
||||
response.errorType === "server" ? 500 : HTTP_CODES[response.codes.status];
|
||||
|
||||
res.status(httpCodes).json(response);
|
||||
};
|
||||
}
|
||||
27
packages/express/src/routes/register.ts
Normal file
27
packages/express/src/routes/register.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import AuthServer, { AuthServerMethod } from "@auth-tools/server";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
const HTTP_CODES = {
|
||||
0: 201,
|
||||
1: 403,
|
||||
2: 400,
|
||||
3: 406,
|
||||
4: 406,
|
||||
5: 403,
|
||||
6: 403,
|
||||
7: 403,
|
||||
9: 403,
|
||||
};
|
||||
|
||||
export function register(authServer: AuthServer): RequestHandler {
|
||||
return async (req, res) => {
|
||||
const response = await (
|
||||
authServer.methods.register as AuthServerMethod<"register">
|
||||
)(req.body);
|
||||
|
||||
const httpCodes =
|
||||
response.errorType === "server" ? 500 : HTTP_CODES[response.codes.status];
|
||||
|
||||
res.status(httpCodes).json(response);
|
||||
};
|
||||
}
|
||||
19
packages/express/tsconfig.json
Normal file
19
packages/express/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2016",
|
||||
"lib": ["ES2016"],
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "Node",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"outDir": "dist",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
import DefaultLogger, { COLORS, Logger } from "@auth-tools/logger";
|
||||
|
||||
DefaultLogger.log("debug", `"debug" log with DefaultLogger`);
|
||||
DefaultLogger.log("info", `"info" log with DefaultLogger`);
|
||||
DefaultLogger.log("warn", `"warn" log with DefaultLogger`);
|
||||
DefaultLogger.log("error", `"error" log with DefaultLogger`);
|
||||
|
||||
//set config after creation
|
||||
DefaultLogger.setConfig({
|
||||
disableColor: true,
|
||||
formatString: "Color disabled: [%l] %d %m",
|
||||
});
|
||||
|
||||
//log shorthands
|
||||
DefaultLogger.debug(`"debug" log with DefaultLogger and updated config`);
|
||||
DefaultLogger.info(`"info" log with DefaultLogger and updated config`);
|
||||
DefaultLogger.warn(`"warn" log with DefaultLogger and updated config`);
|
||||
DefaultLogger.error(`"error" log with DefaultLogger and updated config`);
|
||||
|
||||
//multiple arguments
|
||||
DefaultLogger.log("error", `Argument 1`, "Argument 2");
|
||||
|
||||
//update config again
|
||||
DefaultLogger.setConfig({ disableColor: false, formatString: "Built-In: %m" });
|
||||
|
||||
//builtin Methods
|
||||
DefaultLogger.log("debug", DefaultLogger.color("Red", COLORS.error));
|
||||
DefaultLogger.log("info", DefaultLogger.twoDigits("1"));
|
||||
DefaultLogger.log("warn", DefaultLogger.currentTime());
|
||||
DefaultLogger.log("error", DefaultLogger.currentDate());
|
||||
|
||||
//create custom logger instance
|
||||
const logger2 = new Logger({
|
||||
disableColor: false, //set to true to disable all colors
|
||||
formatString: [
|
||||
//all replacement vars:
|
||||
"Vars: %t = HH:MM:SS",
|
||||
"Vars: %d = YYYY-MM-DD",
|
||||
"Vars: %L = LEVEL",
|
||||
"Vars: %l = level",
|
||||
"Vars: %m = message",
|
||||
].join("\n"),
|
||||
});
|
||||
|
||||
logger2.log("error", "Hallo");
|
||||
|
||||
//update config to disable debug and warn
|
||||
logger2.setConfig({
|
||||
formatString: "Disabled Methods: [%L] %t %m",
|
||||
methods: {
|
||||
debug: false,
|
||||
warn: false,
|
||||
},
|
||||
});
|
||||
|
||||
logger2.debug("Shouldn't log");
|
||||
logger2.info("Should log");
|
||||
logger2.warn("Shouldn't log");
|
||||
logger2.error("Should log");
|
||||
|
||||
//format string with current instance config
|
||||
logger2.setConfig({
|
||||
formatString: "Format String: [%m]",
|
||||
});
|
||||
const formatted = logger2.format("info", "MY CUSTOM STRING");
|
||||
console.log(formatted);
|
||||
@ -1,72 +0,0 @@
|
||||
import { UserData } from "@auth-tools/base";
|
||||
import { Logger } from "@auth-tools/logger";
|
||||
import { AuthServer, AuthServerConfig } from "@auth-tools/server";
|
||||
|
||||
const Users: UserData[] = [];
|
||||
const Tokens: string[] = [];
|
||||
|
||||
const logger = new Logger();
|
||||
|
||||
const authServerConfig: AuthServerConfig = {
|
||||
secrets: {
|
||||
accessToken: "SECRET",
|
||||
refreshToken: "SECRET",
|
||||
},
|
||||
};
|
||||
|
||||
const authServer = new AuthServer(authServerConfig, logger.log);
|
||||
|
||||
authServer.use("getUserByMail", ({ email }) => {
|
||||
const user = Users.find((usr) => usr.email === email) || null;
|
||||
return { serverError: false, user };
|
||||
});
|
||||
|
||||
authServer.use("getUserByName", ({ username }) => {
|
||||
const user = Users.find((usr) => usr.username === username) || null;
|
||||
return { serverError: false, user };
|
||||
});
|
||||
|
||||
authServer.use("storeUser", ({ user }) => {
|
||||
Users.push(user);
|
||||
return { serverError: false };
|
||||
});
|
||||
|
||||
authServer.use("checkToken", ({ refreshToken }) => {
|
||||
const exists = Tokens.includes(refreshToken);
|
||||
return { serverError: false, exists };
|
||||
});
|
||||
|
||||
authServer.use("storeToken", ({ refreshToken }) => {
|
||||
Tokens.push(refreshToken);
|
||||
return { serverError: false };
|
||||
});
|
||||
|
||||
authServer.use("deleteToken", ({ refreshToken }) => {
|
||||
Tokens.splice(Tokens.indexOf(refreshToken), 1);
|
||||
return { serverError: false };
|
||||
});
|
||||
|
||||
authServer.use("validateMail", ({ email }) => {
|
||||
const isValid = email.includes("@");
|
||||
return { serverError: false, isValid };
|
||||
});
|
||||
|
||||
authServer.use("validatePassword", ({ password }) => {
|
||||
const isValid = password.length >= 8;
|
||||
return { serverError: false, isValid };
|
||||
});
|
||||
|
||||
authServer.use("hashPassword", ({ password }) => {
|
||||
const hashedPassword = password.split("").reverse().join("");
|
||||
return { serverError: false, hashedPassword };
|
||||
});
|
||||
|
||||
authServer.use("checkPassword", ({ password, hashedPassword }) => {
|
||||
const matches = password.split("").reverse().join("") === hashedPassword;
|
||||
return { serverError: false, matches };
|
||||
});
|
||||
|
||||
authServer.use("genId", ({}) => {
|
||||
const id = Users.length.toString();
|
||||
return { serverError: false, id };
|
||||
});
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth-tools/server",
|
||||
"version": "0.0.1-alpha.1",
|
||||
"version": "0.0.1-alpha.7",
|
||||
"description": "A structured authentication protocol for Javascript. (server)",
|
||||
"main": "dist/index.js",
|
||||
"repository": "https://github.com/auth-tools/auth-tools",
|
||||
@ -15,7 +15,7 @@
|
||||
"remove": "npm run build:remove && rimraf node_modules yarn.lock package-lock.json pnpm-lock.yaml"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth-tools/base": "^0.0.1-alpha.2",
|
||||
"@auth-tools/base": "^0.0.1-alpha.8",
|
||||
"jsonwebtoken": "^9.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -14,7 +14,7 @@ export function undefinedUseEvent<
|
||||
return (() => {
|
||||
//complain about unset use event callback
|
||||
log("error", `The use "${event}" event is not defined!`);
|
||||
return { ...returnData, serverError: true };
|
||||
return { ...returnData, error: true };
|
||||
}) as UseEventCallbacks<AuthServerUseEvents>[Event];
|
||||
}
|
||||
|
||||
@ -23,6 +23,6 @@ export function undefinedInterceptEvent<
|
||||
Event extends keyof AuthServerInterceptEvents
|
||||
>(): InterceptEventCallbacks<AuthServerInterceptEvents>[Event] {
|
||||
return () => {
|
||||
return { serverError: false, intercepted: false, interceptCode: 0 };
|
||||
return { error: false, intercepted: false, interceptCode: 0 };
|
||||
};
|
||||
}
|
||||
|
||||
@ -21,14 +21,14 @@ export default async function (
|
||||
email: login,
|
||||
});
|
||||
|
||||
if (getUserByMail.serverError) return { serverError: true, user: null };
|
||||
if (getUserByMail.error) return { error: true, user: null };
|
||||
|
||||
//get user by name with value of login
|
||||
const getUserByName = await internal.useEventCallbacks.getUserByName({
|
||||
username: login,
|
||||
});
|
||||
|
||||
if (getUserByName.serverError) return { serverError: true, user: null };
|
||||
if (getUserByName.error) return { error: true, user: null };
|
||||
|
||||
return { serverError: false, user: getUserByMail.user || getUserByName.user };
|
||||
return { error: false, user: getUserByMail.user || getUserByName.user };
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ export function createCheck(
|
||||
refreshToken,
|
||||
});
|
||||
|
||||
if (checkToken.serverError) return authServerError();
|
||||
if (checkToken.error) return authServerError();
|
||||
|
||||
if (!checkToken.exists) {
|
||||
internal.log("debug", 'The "refreshToken" does not exist.');
|
||||
@ -57,7 +57,7 @@ export function createCheck(
|
||||
}
|
||||
|
||||
const decodeAccessToken = decodeToken(
|
||||
refreshToken,
|
||||
accessToken,
|
||||
internal.config.secrets.accessToken
|
||||
);
|
||||
|
||||
@ -72,7 +72,7 @@ export function createCheck(
|
||||
payload: { id: decodeAccessToken.payload.id },
|
||||
});
|
||||
|
||||
if (intercept.serverError) return authServerError();
|
||||
if (intercept.error) return authServerError();
|
||||
|
||||
if (intercept.intercepted)
|
||||
return authError<"check", 9>(
|
||||
@ -82,12 +82,11 @@ export function createCheck(
|
||||
);
|
||||
|
||||
return {
|
||||
auth: {
|
||||
error: false,
|
||||
errorType: "method",
|
||||
message: "Check successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
},
|
||||
error: false,
|
||||
intercepted: false,
|
||||
errorType: "method",
|
||||
message: "Check successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
data: null,
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@ -38,7 +38,7 @@ export function createLogin(
|
||||
|
||||
const getUserByLoginLogin = await getUserByLogin(login, internal);
|
||||
|
||||
if (getUserByLoginLogin.serverError) return authServerError();
|
||||
if (getUserByLoginLogin.error) return authServerError();
|
||||
|
||||
if (!getUserByLoginLogin.user) {
|
||||
if (internal.config.sensitive.logs)
|
||||
@ -60,7 +60,7 @@ export function createLogin(
|
||||
hashedPassword: getUserByLoginLogin.user.hashedPassword,
|
||||
});
|
||||
|
||||
if (checkPassword.serverError) return authServerError();
|
||||
if (checkPassword.error) return authServerError();
|
||||
|
||||
if (!checkPassword.matches) {
|
||||
if (internal.config.sensitive.logs)
|
||||
@ -97,7 +97,7 @@ export function createLogin(
|
||||
payload,
|
||||
});
|
||||
|
||||
if (intercept.serverError) return authServerError();
|
||||
if (intercept.error) return authServerError();
|
||||
|
||||
if (intercept.intercepted)
|
||||
return authError<"login", 9>(
|
||||
@ -110,15 +110,14 @@ export function createLogin(
|
||||
refreshToken,
|
||||
});
|
||||
|
||||
if (storeToken.serverError) return authServerError();
|
||||
if (storeToken.error) return authServerError();
|
||||
|
||||
return {
|
||||
auth: {
|
||||
error: false,
|
||||
errorType: "method",
|
||||
message: "Login successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
},
|
||||
error: false,
|
||||
intercepted: false,
|
||||
errorType: "method",
|
||||
message: "Login successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
data: { accessToken, refreshToken },
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@ -43,7 +43,7 @@ export function createLogout(
|
||||
refreshToken,
|
||||
});
|
||||
|
||||
if (checkToken.serverError) return authServerError();
|
||||
if (checkToken.error) return authServerError();
|
||||
|
||||
if (!checkToken.exists) {
|
||||
internal.log("debug", 'The "refreshToken" does not exist.');
|
||||
@ -55,7 +55,7 @@ export function createLogout(
|
||||
payload: { id: decodeRefreshToken.payload.id },
|
||||
});
|
||||
|
||||
if (intercept.serverError) return authServerError();
|
||||
if (intercept.error) return authServerError();
|
||||
|
||||
if (intercept.intercepted)
|
||||
return authError<"logout", 9>(
|
||||
@ -68,15 +68,14 @@ export function createLogout(
|
||||
refreshToken,
|
||||
});
|
||||
|
||||
if (deleteToken.serverError) return authServerError();
|
||||
if (deleteToken.error) return authServerError();
|
||||
|
||||
return {
|
||||
auth: {
|
||||
error: false,
|
||||
errorType: "method",
|
||||
message: "Logout successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
},
|
||||
error: false,
|
||||
intercepted: false,
|
||||
errorType: "method",
|
||||
message: "Logout successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
data: null,
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@ -43,7 +43,7 @@ export function createRefresh(
|
||||
refreshToken,
|
||||
});
|
||||
|
||||
if (checkToken.serverError) return authServerError();
|
||||
if (checkToken.error) return authServerError();
|
||||
|
||||
if (!checkToken.exists) {
|
||||
internal.log("debug", 'The "refreshToken" does not exist.');
|
||||
@ -55,7 +55,7 @@ export function createRefresh(
|
||||
payload: { id: decodeRefreshToken.payload.id },
|
||||
});
|
||||
|
||||
if (intercept.serverError) return authServerError();
|
||||
if (intercept.error) return authServerError();
|
||||
|
||||
if (intercept.intercepted)
|
||||
return authError<"refresh", 9>(
|
||||
@ -71,12 +71,11 @@ export function createRefresh(
|
||||
);
|
||||
|
||||
return {
|
||||
auth: {
|
||||
error: false,
|
||||
errorType: "method",
|
||||
message: "Refresh successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
},
|
||||
error: false,
|
||||
intercepted: false,
|
||||
errorType: "method",
|
||||
message: "Refresh successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
data: { accessToken },
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@ -42,7 +42,7 @@ export function createRegister(
|
||||
email,
|
||||
});
|
||||
|
||||
if (validateMail.serverError) return authServerError();
|
||||
if (validateMail.error) return authServerError();
|
||||
|
||||
if (!validateMail.isValid) {
|
||||
internal.log("debug", 'The "email" is malformed.');
|
||||
@ -54,7 +54,7 @@ export function createRegister(
|
||||
password,
|
||||
});
|
||||
|
||||
if (validatePassword.serverError) return authServerError();
|
||||
if (validatePassword.error) return authServerError();
|
||||
|
||||
if (!validatePassword.isValid) {
|
||||
internal.log("debug", 'The "password" is too weak.');
|
||||
@ -63,7 +63,7 @@ export function createRegister(
|
||||
|
||||
const getUserByLoginEmail = await getUserByLogin(email, internal);
|
||||
|
||||
if (getUserByLoginEmail.serverError) return authServerError();
|
||||
if (getUserByLoginEmail.error) return authServerError();
|
||||
|
||||
if (getUserByLoginEmail.user) {
|
||||
if (internal.config.sensitive.logs)
|
||||
@ -77,7 +77,7 @@ export function createRegister(
|
||||
|
||||
const getUserByLoginName = await getUserByLogin(username, internal);
|
||||
|
||||
if (getUserByLoginName.serverError) return authServerError();
|
||||
if (getUserByLoginName.error) return authServerError();
|
||||
|
||||
if (getUserByLoginName.user) {
|
||||
if (internal.config.sensitive.logs)
|
||||
@ -96,14 +96,14 @@ export function createRegister(
|
||||
password,
|
||||
});
|
||||
|
||||
if (hashPassword.serverError) return authServerError();
|
||||
if (hashPassword.error) return authServerError();
|
||||
|
||||
const genId = await internal.useEventCallbacks.genId({
|
||||
email,
|
||||
username,
|
||||
});
|
||||
|
||||
if (genId.serverError) return authServerError();
|
||||
if (genId.error) return authServerError();
|
||||
|
||||
const user: User<"id" | "email" | "username" | "hashedPassword"> = {
|
||||
id: genId.id,
|
||||
@ -116,7 +116,7 @@ export function createRegister(
|
||||
user,
|
||||
});
|
||||
|
||||
if (intercept.serverError) return authServerError();
|
||||
if (intercept.error) return authServerError();
|
||||
|
||||
if (intercept.intercepted)
|
||||
return authError<"register", 9>(
|
||||
@ -127,15 +127,14 @@ export function createRegister(
|
||||
|
||||
const storeUser = await internal.useEventCallbacks.storeUser({ user });
|
||||
|
||||
if (storeUser.serverError) return authServerError();
|
||||
if (storeUser.error) return authServerError();
|
||||
|
||||
return {
|
||||
auth: {
|
||||
error: false,
|
||||
errorType: "method",
|
||||
message: "Registration successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
},
|
||||
error: false,
|
||||
intercepted: false,
|
||||
errorType: "method",
|
||||
message: "Registration successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
data: { id: user.id, email: user.email, username: user.username },
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@ -40,12 +40,11 @@ export function createValidate(
|
||||
}
|
||||
|
||||
return {
|
||||
auth: {
|
||||
error: false,
|
||||
errorType: "method",
|
||||
message: "Validation successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
},
|
||||
error: false,
|
||||
intercepted: false,
|
||||
errorType: "method",
|
||||
message: "Validation successful.",
|
||||
codes: { status: 0, intercept: 0 },
|
||||
data: { id: decodeAccessToken.payload.id },
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@ -9,14 +9,13 @@ export function authError<
|
||||
interceptCode: number = 0
|
||||
): AuthResponse<Method> {
|
||||
return {
|
||||
auth: {
|
||||
error: true,
|
||||
errorType: "method",
|
||||
message: message,
|
||||
codes: {
|
||||
status: statusCode,
|
||||
intercept: interceptCode,
|
||||
},
|
||||
error: true,
|
||||
intercepted: interceptCode === 0 ? false : true,
|
||||
errorType: "method",
|
||||
message: message,
|
||||
codes: {
|
||||
status: statusCode,
|
||||
intercept: interceptCode,
|
||||
},
|
||||
data: null,
|
||||
} as AuthResponse<Method>;
|
||||
@ -24,12 +23,11 @@ export function authError<
|
||||
|
||||
export function authServerError(): AuthProtocol[keyof AuthProtocol]["responses"]["server_5"] {
|
||||
return {
|
||||
auth: {
|
||||
error: true,
|
||||
errorType: "server",
|
||||
message: "An error occurred on the server. Please try again later.",
|
||||
codes: { status: 5, intercept: 0 },
|
||||
},
|
||||
error: true,
|
||||
intercepted: false,
|
||||
errorType: "server",
|
||||
message: "An error occurred on the server. Please try again later.",
|
||||
codes: { status: 5, intercept: 0 },
|
||||
data: null,
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user