From 12ec567afa73822a2cb834963b0fcd939facf149 Mon Sep 17 00:00:00 2001 From: mamor87 Date: Sat, 23 Aug 2025 22:48:37 +0200 Subject: [PATCH] init --- .gitignore | 5 + .npmignore | 7 + LICENSE | 21 + README.md | 3 + package-lock.json | 565 ++++++++++++++++++++++ package.json | 26 + src/index.ts | 12 + src/models/account.ts | 32 ++ src/models/group.ts | 21 + src/models/organization.ts | 10 + src/models/registration.ts | 25 + src/models/right.ts | 10 + src/models/session.ts | 16 + src/models/sign.in.ts | 13 + src/services/mail.verification.service.ts | 25 + src/services/password.service.ts | 24 + src/services/session.service.ts | 37 ++ src/services/token.service.ts | 40 ++ tsconfig.json | 27 ++ 19 files changed, 919 insertions(+) create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/index.ts create mode 100644 src/models/account.ts create mode 100644 src/models/group.ts create mode 100644 src/models/organization.ts create mode 100644 src/models/registration.ts create mode 100644 src/models/right.ts create mode 100644 src/models/session.ts create mode 100644 src/models/sign.in.ts create mode 100644 src/services/mail.verification.service.ts create mode 100644 src/services/password.service.ts create mode 100644 src/services/session.service.ts create mode 100644 src/services/token.service.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8b7d5d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.vscode +.idea +coverage +dist +node_modules diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..e9a8336 --- /dev/null +++ b/.npmignore @@ -0,0 +1,7 @@ +.vscode +.idea +node_modules +coverage +src +.gitignore +tsconfig.json \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2efc0b9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Markus Morgenstern + +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. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..aa5fb7b --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Authentication + +This Package holds all Ports (Contracts) to implement for a Authentication. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ac57642 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,565 @@ +{ + "name": "@apihub24/authentication", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@apihub24/authentication", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "rimraf": "^6.0.1", + "typescript": "^5.9.2" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..a59861e --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "@apihub24/authentication", + "version": "1.0.0", + "description": "", + "main": "dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "rimraf ./dist && tsc", + "pub": "npm publish", + "rel": "npm i && npm run build" + }, + "devDependencies": { + "rimraf": "^6.0.1", + "typescript": "^5.9.2" + }, + "keywords": [], + "author": { + "email": "markusmorgenstern87@outlook.de", + "name": "Markus Morgenstern", + "url": "https://git.apihub24.de/" + }, + "license": "MIT", + "publishConfig": { + "access": "public" + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..378a316 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,12 @@ +export * from "./models/account"; +export * from "./models/group"; +export * from "./models/organization"; +export * from "./models/registration"; +export * from "./models/right"; +export * from "./models/session"; +export * from "./models/sign.in"; + +export * from "./services/mail.verification.service"; +export * from "./services/password.service"; +export * from "./services/session.service"; +export * from "./services/token.service"; diff --git a/src/models/account.ts b/src/models/account.ts new file mode 100644 index 0000000..a8a0e1b --- /dev/null +++ b/src/models/account.ts @@ -0,0 +1,32 @@ +import { IGroup } from "./group"; + +/** + * represent the Users Account + */ +export interface IAccount { + id: string; + /** + * the Accounts name + */ + accountName: string; + /** + * the hashed Password + */ + passwordHash: string; + /** + * a E-Mail Address for this Account + */ + email: string; + /** + * represents if the E-Mail Address was verified + */ + emailVerified: boolean; + /** + * represents if the User was activated for Login + */ + active: boolean; + /** + * the Groups this User was member + */ + groups: IGroup[]; +} diff --git a/src/models/group.ts b/src/models/group.ts new file mode 100644 index 0000000..5eb0bc6 --- /dev/null +++ b/src/models/group.ts @@ -0,0 +1,21 @@ +import { IOrganization } from "./organization"; +import { IRight } from "./right"; + +/** + * represents a Group that a User can Join + */ +export interface IGroup { + id: string; + /** + * the Name of the Group + */ + name: string; + /** + * the Organization in that the Group are + */ + organization: IOrganization; + /** + * the Rights that have the Group + */ + rights: IRight[]; +} diff --git a/src/models/organization.ts b/src/models/organization.ts new file mode 100644 index 0000000..0bca9e7 --- /dev/null +++ b/src/models/organization.ts @@ -0,0 +1,10 @@ +/** + * represent a Organization Unit + */ +export interface IOrganization { + id: string; + /** + * the Name of the Organization + */ + name: string; +} diff --git a/src/models/registration.ts b/src/models/registration.ts new file mode 100644 index 0000000..21a5838 --- /dev/null +++ b/src/models/registration.ts @@ -0,0 +1,25 @@ +/** + * represents Registration Data + */ +export interface IRegistration { + /** + * the Account Name to register + */ + accountName: string; + /** + * the Password to register + */ + password: string; + /** + * the repeated Password + */ + passwordComparer: string; + /** + * the E-Mail Address to register + */ + email: string; + /** + * the Group Ids the Account must be Part + */ + groupIds: string[]; +} diff --git a/src/models/right.ts b/src/models/right.ts new file mode 100644 index 0000000..540d45b --- /dev/null +++ b/src/models/right.ts @@ -0,0 +1,10 @@ +/** + * represent a Application Right + */ +export interface IRight { + id: string; + /** + * the Right Name + */ + name: string; +} diff --git a/src/models/session.ts b/src/models/session.ts new file mode 100644 index 0000000..c9b67b6 --- /dev/null +++ b/src/models/session.ts @@ -0,0 +1,16 @@ +import { IAccount } from "./account"; + +/** + * represents a Session + */ +export interface ISession { + id: string; + /** + * the Account of the Session + */ + account: IAccount; + /** + * some MetaData + */ + metaData: Record; +} diff --git a/src/models/sign.in.ts b/src/models/sign.in.ts new file mode 100644 index 0000000..d242ebc --- /dev/null +++ b/src/models/sign.in.ts @@ -0,0 +1,13 @@ +/** + * represent a Sign In Request + */ +export interface ISignIn { + /** + * the Account Name to sign in + */ + accountName: string; + /** + * the Password to sign in + */ + password: string; +} diff --git a/src/services/mail.verification.service.ts b/src/services/mail.verification.service.ts new file mode 100644 index 0000000..75743a3 --- /dev/null +++ b/src/services/mail.verification.service.ts @@ -0,0 +1,25 @@ +import { IAccount } from "../models/account"; + +/** + * @interface IMailVerificationService + * @description Defines the contract for a service that handles email verification, + * including sending verification emails and validating verification codes. + */ +export interface IMailVerificationService { + /** + * Sends a verification email to a specified account. + * The implementation should generate a unique verification code and send it to the account's email address. + * @param account The `IAccount` object to which the verification email should be sent. + * @returns A promise that resolves to `void` upon successful sending of the email. + */ + sendVerificationMail(account: IAccount): Promise; + + /** + * Verifies a given code against a user's email address. + * This method checks if the provided code matches the one sent to the specified email address. + * @param email The email address to verify. + * @param code The verification code submitted by the user. + * @returns A promise that resolves to `true` if the code is valid, otherwise `false`. + */ + verify(email: string, code: string): Promise; +} diff --git a/src/services/password.service.ts b/src/services/password.service.ts new file mode 100644 index 0000000..7678151 --- /dev/null +++ b/src/services/password.service.ts @@ -0,0 +1,24 @@ +/** + * @interface IPasswordService + * @description Defines the contract for a service that handles secure password operations, + * including hashing and verification. + */ +export interface IPasswordService { + /** + * Hashes a plain-text password to a secure, one-way hash. + * This method should be used to store passwords securely in a database. + * @param plainTextPassword The password string in plain text to be hashed. + * @returns A promise that resolves to the hashed password string. + */ + hash(plainTextPassword: string): Promise; + + /** + * Verifies a plain-text password against a stored password hash. + * This method is crucial for user authentication, ensuring the entered password + * matches the stored hash without needing to store the plain-text version. + * @param plainTextPassword The password string in plain text provided by the user. + * @param passwordHash The stored, hashed password string to compare against. + * @returns A promise that resolves to `true` if the plain-text password matches the hash, otherwise `false`. + */ + verify(plainTextPassword: string, passwordHash: string): Promise; +} diff --git a/src/services/session.service.ts b/src/services/session.service.ts new file mode 100644 index 0000000..5f46a93 --- /dev/null +++ b/src/services/session.service.ts @@ -0,0 +1,37 @@ +import { IAccount } from "../models/account"; +import { ISession } from "../models/session"; + +/** + * @interface ISessionService + * @description Defines the contract for a service that manages user sessions. + * It provides methods for creating, retrieving, and removing sessions. + */ +export interface ISessionService { + /** + * Creates a new session for a given account. + * @param account The `IAccount` object for which to create the session. + * @returns A promise that resolves to the newly created `ISession` object. + */ + create(account: IAccount): Promise; + + /** + * Retrieves sessions that match a given filter. + * @param filter A function that takes an `IAccount` object and returns a boolean, serving as the condition for selecting sessions. + * @returns A promise that resolves to an array of `ISession` objects. + */ + getBy(filter: (account: IAccount) => boolean): Promise; + + /** + * Retrieves a single session by its unique identifier. + * @param sessionId The ID of the session to retrieve. + * @returns A promise that resolves to the `ISession` object, or `null` if no session is found. + */ + getById(sessionId: string): Promise; + + /** + * Removes a session based on its unique identifier. + * @param sessionId The ID of the session to remove. + * @returns A promise that resolves to `void` after the session has been removed. + */ + remove(sessionId: string): Promise; +} diff --git a/src/services/token.service.ts b/src/services/token.service.ts new file mode 100644 index 0000000..f2f6a85 --- /dev/null +++ b/src/services/token.service.ts @@ -0,0 +1,40 @@ +import { IAccount } from "../models/account"; +import { ISession } from "../models/session"; + +export type Algorithm = "HS256" | "HS384" | "HS512"; + +/** + * @interface ITokenService + * @description Defines the contract for a service that handles token-related operations, + * such as generation, validation, and extraction of account information from tokens. + */ +export interface ITokenService { + /** + * Generates a new JWT token for a given session and subject. + * @param session The session object containing data to be included in the token payload. + * @param subject The subject of the token, typically the account name or ID. + * @param expires Optional string specifying the token's expiration duration (e.g., '1h', '30m'). + * @param algorithm Optional string specifying the signing algorithm (e.g., 'HS256', 'RS512'). + * @returns A promise that resolves to the generated token string. + */ + generate( + session: ISession, + subject: string, + expires?: string, + algorithm?: Algorithm + ): Promise; + + /** + * Validates a given token to ensure it is authentic and not expired. + * @param token The token string to be validated. + * @returns A promise that resolves to `true` if the token is valid, otherwise `false`. + */ + validate(token: string): Promise; + + /** + * Extracts and retrieves the account associated with a given token. + * @param token The token string from which to extract account information. + * @returns A promise that resolves to the `IAccount` object or `null` if the token is invalid or no account is found. + */ + getAccount(token: string): Promise; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..3224568 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "module": "nodenext", + "moduleResolution": "nodenext", + "resolvePackageJsonExports": true, + "esModuleInterop": true, + "isolatedModules": true, + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "ES2023", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": true, + "forceConsistentCasingInFileNames": true, + "noImplicitAny": false, + "strictBindCallApply": false, + "noFallthroughCasesInSwitch": false + }, + "include": ["./src"], + "exclude": ["**/*.spec.ts", "**/*.mock.ts"] +}