diff --git a/packages/base/package.json b/packages/base/package.json index 6ffff23..dfabde2 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -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", diff --git a/packages/base/src/events/intercept.ts b/packages/base/src/events/intercept.ts index d7606a3..24de94f 100644 --- a/packages/base/src/events/intercept.ts +++ b/packages/base/src/events/intercept.ts @@ -14,7 +14,7 @@ export type InterceptEventsDefinition = { type InterceptEvent = { data: ClassInterceptEvents["data"]; return: { - serverError?: boolean; + error?: boolean; intercepted: boolean; interceptCode: number; }; diff --git a/packages/base/src/events/use.ts b/packages/base/src/events/use.ts index 5831a36..fe45780 100644 --- a/packages/base/src/events/use.ts +++ b/packages/base/src/events/use.ts @@ -14,7 +14,7 @@ export type UseEventsDefinition = { //data for an use event type UseEvent = { data: ClassUseEvents["data"]; - return: { serverError?: boolean } & ClassUseEvents["return"]; + return: { error?: boolean } & ClassUseEvents["return"]; }; //all use events diff --git a/packages/base/src/protocol/index.ts b/packages/base/src/protocol/index.ts index 5ec6530..40bef2d 100644 --- a/packages/base/src/protocol/index.ts +++ b/packages/base/src/protocol/index.ts @@ -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< diff --git a/packages/base/src/protocol/messages.ts b/packages/base/src/protocol/messages.ts index 4b07d01..775414a 100644 --- a/packages/base/src/protocol/messages.ts +++ b/packages/base/src/protocol/messages.ts @@ -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.'; diff --git a/packages/client/package.json b/packages/client/package.json index 703c07b..3f9c3e2 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -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" diff --git a/packages/client/src/auth.ts b/packages/client/src/auth.ts new file mode 100644 index 0000000..c6d84ce --- /dev/null +++ b/packages/client/src/auth.ts @@ -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 = + | { clientError: true; res: null } + | { clientError: false; res: AuthResponse }; + +export type AuthClientConnector = ( + method: MethodName, + data: AuthRequest +) => Promisify>; + +type TokenTypes = "accessToken" | "refreshToken"; + +//config passed by user to class +export type AuthClientConfig = { + connector: AuthClientConnector; +}; + +//all use events +export type AuthClientUseEvents = { + getToken: { + data: { type: TokenTypes }; + return: { token: User[TokenTypes] | null }; + }; + storeToken: { + data: { type: TokenTypes; token: User[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 +) => Promise>; + +type AuthClientMethods = { + [MethodName in keyof AuthProtocol]: AuthClientMethod; +}; + +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 = { + 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), + }; + } +} diff --git a/packages/client/src/events.ts b/packages/client/src/events.ts new file mode 100644 index 0000000..58a68ea --- /dev/null +++ b/packages/client/src/events.ts @@ -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[Event] { + return (() => { + //complain about unset use event callback + log("error", `The use "${event}" event is not defined!`); + return { ...returnData, error: true }; + }) as UseEventCallbacks[Event]; +} diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index e69de29..ca14b40 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -0,0 +1,7 @@ +export { AuthClient as default } from "./auth"; +export { + AuthClient, + AuthClientConfig, + AuthClientConnector, + AuthClientMethod, +} from "./auth"; diff --git a/packages/client/src/methods/_template.ts.txt b/packages/client/src/methods/_template.ts.txt new file mode 100644 index 0000000..d3a41a9 --- /dev/null +++ b/packages/client/src/methods/_template.ts.txt @@ -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 +): AuthClientMethod<"_method"> { + return async ({}) => {}; +} diff --git a/packages/client/src/methods/check.ts b/packages/client/src/methods/check.ts new file mode 100644 index 0000000..13af231 --- /dev/null +++ b/packages/client/src/methods/check.ts @@ -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 +): 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; + }; +} diff --git a/packages/client/src/methods/login.ts b/packages/client/src/methods/login.ts new file mode 100644 index 0000000..c68f2b9 --- /dev/null +++ b/packages/client/src/methods/login.ts @@ -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 +): 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; + }; +} diff --git a/packages/client/src/methods/logout.ts b/packages/client/src/methods/logout.ts new file mode 100644 index 0000000..f083364 --- /dev/null +++ b/packages/client/src/methods/logout.ts @@ -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 +): 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; + }; +} diff --git a/packages/client/src/methods/refresh.ts b/packages/client/src/methods/refresh.ts new file mode 100644 index 0000000..38f9e78 --- /dev/null +++ b/packages/client/src/methods/refresh.ts @@ -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 +): 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; + }; +} diff --git a/packages/client/src/methods/register.ts b/packages/client/src/methods/register.ts new file mode 100644 index 0000000..d8658c7 --- /dev/null +++ b/packages/client/src/methods/register.ts @@ -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 +): AuthClientMethod<"register"> { + return async ({ email, username, password }) => { + const registerResponse = await ( + internal.config.connector as AuthClientConnector<"register"> + )("register", { email, username, password }); + + return registerResponse; + }; +} diff --git a/packages/client/src/methods/validate.ts b/packages/client/src/methods/validate.ts new file mode 100644 index 0000000..1160ec0 --- /dev/null +++ b/packages/client/src/methods/validate.ts @@ -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 +): AuthClientMethod<"validate"> { + return async ({ accessToken }) => { + const validateResponse = await ( + internal.config.connector as AuthClientConnector<"validate"> + )("validate", { accessToken }); + + return validateResponse; + }; +} diff --git a/packages/express/LICENSE b/packages/express/LICENSE new file mode 100644 index 0000000..6868a4d --- /dev/null +++ b/packages/express/LICENSE @@ -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. diff --git a/packages/express/local/index.ts b/packages/express/local/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/express/package.json b/packages/express/package.json new file mode 100644 index 0000000..e5a0212 --- /dev/null +++ b/packages/express/package.json @@ -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 ", + "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" + ] +} diff --git a/packages/express/src/express.ts b/packages/express/src/express.ts new file mode 100644 index 0000000..f2833ca --- /dev/null +++ b/packages/express/src/express.ts @@ -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, + }; +} diff --git a/packages/express/src/index.ts b/packages/express/src/index.ts new file mode 100644 index 0000000..4282c0d --- /dev/null +++ b/packages/express/src/index.ts @@ -0,0 +1,2 @@ +export { authExpress as default } from "./express"; +export { authExpress } from "./express"; diff --git a/packages/express/src/middleWares/validate.ts b/packages/express/src/middleWares/validate.ts new file mode 100644 index 0000000..c70ef97 --- /dev/null +++ b/packages/express/src/middleWares/validate.ts @@ -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(); + }; +} diff --git a/packages/express/src/routes/check.ts b/packages/express/src/routes/check.ts new file mode 100644 index 0000000..d041d6e --- /dev/null +++ b/packages/express/src/routes/check.ts @@ -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); + }; +} diff --git a/packages/express/src/routes/login.ts b/packages/express/src/routes/login.ts new file mode 100644 index 0000000..d568951 --- /dev/null +++ b/packages/express/src/routes/login.ts @@ -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); + }; +} diff --git a/packages/express/src/routes/logout.ts b/packages/express/src/routes/logout.ts new file mode 100644 index 0000000..e207eb3 --- /dev/null +++ b/packages/express/src/routes/logout.ts @@ -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); + }; +} diff --git a/packages/express/src/routes/refresh.ts b/packages/express/src/routes/refresh.ts new file mode 100644 index 0000000..09086fb --- /dev/null +++ b/packages/express/src/routes/refresh.ts @@ -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); + }; +} diff --git a/packages/express/src/routes/register.ts b/packages/express/src/routes/register.ts new file mode 100644 index 0000000..13e4b70 --- /dev/null +++ b/packages/express/src/routes/register.ts @@ -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); + }; +} diff --git a/packages/express/tsconfig.json b/packages/express/tsconfig.json new file mode 100644 index 0000000..ce1e038 --- /dev/null +++ b/packages/express/tsconfig.json @@ -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/**/*"] +} diff --git a/packages/logger/local/index.ts b/packages/logger/local/index.ts index a841710..e69de29 100644 --- a/packages/logger/local/index.ts +++ b/packages/logger/local/index.ts @@ -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); diff --git a/packages/server/local/index.ts b/packages/server/local/index.ts index f1bc454..e69de29 100644 --- a/packages/server/local/index.ts +++ b/packages/server/local/index.ts @@ -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 }; -}); diff --git a/packages/server/package.json b/packages/server/package.json index 2261f16..0933947 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -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": { diff --git a/packages/server/src/events.ts b/packages/server/src/events.ts index 3c991af..9665c11 100644 --- a/packages/server/src/events.ts +++ b/packages/server/src/events.ts @@ -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[Event]; } @@ -23,6 +23,6 @@ export function undefinedInterceptEvent< Event extends keyof AuthServerInterceptEvents >(): InterceptEventCallbacks[Event] { return () => { - return { serverError: false, intercepted: false, interceptCode: 0 }; + return { error: false, intercepted: false, interceptCode: 0 }; }; } diff --git a/packages/server/src/getUserByLogin.ts b/packages/server/src/getUserByLogin.ts index 2c9c891..98968d2 100644 --- a/packages/server/src/getUserByLogin.ts +++ b/packages/server/src/getUserByLogin.ts @@ -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 }; } diff --git a/packages/server/src/methods/check.ts b/packages/server/src/methods/check.ts index 4cf6e78..e02300a 100644 --- a/packages/server/src/methods/check.ts +++ b/packages/server/src/methods/check.ts @@ -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) { diff --git a/packages/server/src/methods/login.ts b/packages/server/src/methods/login.ts index 4411de3..912dee7 100644 --- a/packages/server/src/methods/login.ts +++ b/packages/server/src/methods/login.ts @@ -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) { diff --git a/packages/server/src/methods/logout.ts b/packages/server/src/methods/logout.ts index 2f3e307..190423c 100644 --- a/packages/server/src/methods/logout.ts +++ b/packages/server/src/methods/logout.ts @@ -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) { diff --git a/packages/server/src/methods/refresh.ts b/packages/server/src/methods/refresh.ts index 106d106..5b982df 100644 --- a/packages/server/src/methods/refresh.ts +++ b/packages/server/src/methods/refresh.ts @@ -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) { diff --git a/packages/server/src/methods/register.ts b/packages/server/src/methods/register.ts index ecdc4c8..5437061 100644 --- a/packages/server/src/methods/register.ts +++ b/packages/server/src/methods/register.ts @@ -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) { diff --git a/packages/server/src/methods/validate.ts b/packages/server/src/methods/validate.ts index 7a6bde3..aa8f978 100644 --- a/packages/server/src/methods/validate.ts +++ b/packages/server/src/methods/validate.ts @@ -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) { diff --git a/packages/server/src/senders.ts b/packages/server/src/senders.ts index 9110efc..9fa4bf9 100644 --- a/packages/server/src/senders.ts +++ b/packages/server/src/senders.ts @@ -9,14 +9,13 @@ export function authError< interceptCode: number = 0 ): AuthResponse { 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; @@ -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, }; }