mirror of
https://github.com/KeyZox71/knl_meowscendence.git
synced 2025-08-14 12:32:54 +02:00
「🏗️」 wip: refactor working
This commit is contained in:
1
Justfile
1
Justfile
@ -4,6 +4,7 @@
|
||||
# For launching the authentification api
|
||||
@auth $FASTIFY_LOG_LEVEL="info" $FASTIFY_PRETTY_LOGS="true":
|
||||
fastify start src/api/auth/default.js
|
||||
|
||||
# For launching the user data api
|
||||
@user $FASTIFY_LOG_LEVEL="info" $FASTIFY_PRETTY_LOGS="true":
|
||||
fastify start src/api/user/default.js
|
||||
|
@ -1,3 +1,5 @@
|
||||
name: ft_transcendence
|
||||
|
||||
services:
|
||||
front:
|
||||
container_name: transcendence-front
|
||||
@ -5,7 +7,7 @@ services:
|
||||
dockerfile: docker/front/Dockerfile
|
||||
context: ..
|
||||
ports:
|
||||
- 8443:443
|
||||
- ${OUT_PORT}:443
|
||||
environment:
|
||||
SERVER_NAME: localhost
|
||||
depends_on:
|
||||
@ -15,35 +17,48 @@ services:
|
||||
condition: service_started
|
||||
networks:
|
||||
- front
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
restart: unless-stopped
|
||||
user-api:
|
||||
container_name: transcendence-api-user
|
||||
build:
|
||||
dockerfile: docker/api-base/Dockerfile
|
||||
context: ..
|
||||
tags:
|
||||
- api-base
|
||||
volumes:
|
||||
- db-user:/db
|
||||
networks:
|
||||
- front
|
||||
- back
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- API_TARGET=user
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
restart: unless-stopped
|
||||
auth-api:
|
||||
container_name: transcendence-api-auth
|
||||
build:
|
||||
dockerfile: docker/api-base/Dockerfile
|
||||
context: ..
|
||||
volumes:
|
||||
- db-auth:/db
|
||||
networks:
|
||||
- front
|
||||
- back
|
||||
environment:
|
||||
- TZ=Europe/Paris
|
||||
- API_TARGET=auth
|
||||
|
||||
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
front:
|
||||
external: false
|
||||
name: front-backend
|
||||
name: transcendence-front
|
||||
back:
|
||||
external: false
|
||||
name: trans-backend
|
||||
name: transcendence-back
|
||||
|
||||
volumes:
|
||||
db-auth:
|
||||
name: transcendence-api-auth-db
|
||||
db-user:
|
||||
name: transcendence-api-user-db
|
||||
|
@ -6,14 +6,15 @@
|
||||
"bcrypt": "^6.0.0",
|
||||
"better-sqlite3": "^12.2.0",
|
||||
"fastify": "^5.4.0",
|
||||
"fastify-cli": "^7.4.0"
|
||||
"fastify-cli": "^7.4.0",
|
||||
"google-auth-library": "^10.1.0"
|
||||
},
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"typescript": "^5.8.3",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"pino-pretty": "^13.0.0",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.5"
|
||||
}
|
||||
}
|
||||
|
180
pnpm-lock.yaml
generated
180
pnpm-lock.yaml
generated
@ -29,6 +29,9 @@ importers:
|
||||
fastify-cli:
|
||||
specifier: ^7.4.0
|
||||
version: 7.4.0
|
||||
google-auth-library:
|
||||
specifier: ^10.1.0
|
||||
version: 10.1.0
|
||||
devDependencies:
|
||||
'@tailwindcss/vite':
|
||||
specifier: ^4.1.11
|
||||
@ -455,6 +458,10 @@ packages:
|
||||
abstract-logging@2.0.1:
|
||||
resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
|
||||
|
||||
agent-base@7.1.4:
|
||||
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
ajv-formats@3.0.1:
|
||||
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
|
||||
peerDependencies:
|
||||
@ -491,6 +498,9 @@ packages:
|
||||
resolution: {integrity: sha512-eGbYq2CT+tos1fBwLQ/tkBt9J5M3JEHjku4hbvQUePCckkvVf14xWj+1m7dGoK81M/fOjFT7yM9UMeKT/+vFLQ==}
|
||||
engines: {node: 20.x || 22.x || 23.x || 24.x}
|
||||
|
||||
bignumber.js@9.3.1:
|
||||
resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==}
|
||||
|
||||
bindings@1.5.0:
|
||||
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
|
||||
|
||||
@ -500,6 +510,9 @@ packages:
|
||||
bn.js@4.12.2:
|
||||
resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==}
|
||||
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
||||
|
||||
buffer@5.7.1:
|
||||
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
|
||||
|
||||
@ -538,9 +551,22 @@ packages:
|
||||
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
data-uri-to-buffer@4.0.1:
|
||||
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
dateformat@4.6.3:
|
||||
resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
|
||||
|
||||
debug@4.4.1:
|
||||
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decompress-response@6.0.0:
|
||||
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
||||
engines: {node: '>=10'}
|
||||
@ -587,6 +613,9 @@ packages:
|
||||
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
extend@3.0.2:
|
||||
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
|
||||
|
||||
fast-copy@3.0.2:
|
||||
resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==}
|
||||
|
||||
@ -647,6 +676,10 @@ packages:
|
||||
picomatch:
|
||||
optional: true
|
||||
|
||||
fetch-blob@3.2.0:
|
||||
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
|
||||
engines: {node: ^12.20 || >= 14.13}
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
||||
|
||||
@ -658,6 +691,10 @@ packages:
|
||||
resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
formdata-polyfill@4.0.10:
|
||||
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
|
||||
fs-constants@1.0.0:
|
||||
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
||||
|
||||
@ -666,6 +703,14 @@ packages:
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
gaxios@7.1.1:
|
||||
resolution: {integrity: sha512-Odju3uBUJyVCkW64nLD4wKLhbh93bh6vIg/ZIXkWiLPBrdgtc65+tls/qml+un3pr6JqYVFDZbbmLDQT68rTOQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
gcp-metadata@7.0.1:
|
||||
resolution: {integrity: sha512-UcO3kefx6dCcZkgcTGgVOTFb7b1LlQ02hY1omMjjrrBzkajRMCFgYOjs7J71WqnuG1k2b+9ppGL7FsOfhZMQKQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
generify@4.2.0:
|
||||
resolution: {integrity: sha512-b4cVhbPfbgbCZtK0dcUc1lASitXGEAIqukV5DDAyWm25fomWnV+C+a1yXvqikcRZXHN2j0pSDyj3cTfzq8pC7Q==}
|
||||
hasBin: true
|
||||
@ -673,9 +718,21 @@ packages:
|
||||
github-from-package@0.0.0:
|
||||
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
|
||||
|
||||
google-auth-library@10.1.0:
|
||||
resolution: {integrity: sha512-GspVjZj1RbyRWpQ9FbAXMKjFGzZwDKnUHi66JJ+tcjcu5/xYAP1pdlWotCuIkMwjfVsxxDvsGZXGLzRt72D0sQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
google-logging-utils@1.1.1:
|
||||
resolution: {integrity: sha512-rcX58I7nqpu4mbKztFeOAObbomBbHU2oIb/d3tJfF3dizGSApqtSwYJigGCooHdnMyQBIw8BrWyK96w3YXgr6A==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
||||
gtoken@8.0.0:
|
||||
resolution: {integrity: sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
@ -683,6 +740,10 @@ packages:
|
||||
help-me@5.0.0:
|
||||
resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==}
|
||||
|
||||
https-proxy-agent@7.0.6:
|
||||
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
ieee754@1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
|
||||
@ -713,12 +774,21 @@ packages:
|
||||
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
json-bigint@1.0.0:
|
||||
resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==}
|
||||
|
||||
json-schema-ref-resolver@2.0.1:
|
||||
resolution: {integrity: sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==}
|
||||
|
||||
json-schema-traverse@1.0.0:
|
||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||
|
||||
jwa@2.0.1:
|
||||
resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==}
|
||||
|
||||
jws@4.0.0:
|
||||
resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==}
|
||||
|
||||
light-my-request@6.6.0:
|
||||
resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==}
|
||||
|
||||
@ -825,6 +895,9 @@ packages:
|
||||
mnemonist@0.40.3:
|
||||
resolution: {integrity: sha512-Vjyr90sJ23CKKH/qPAgUKicw/v6pRoamxIEDFOF8uSgFME7DqPRpHgRTejWVjkdGg5dXj0/NyxZHZ9bcjH+2uQ==}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
nanoid@3.3.11:
|
||||
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
@ -841,6 +914,15 @@ packages:
|
||||
resolution: {integrity: sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==}
|
||||
engines: {node: ^18 || ^20 || >= 21}
|
||||
|
||||
node-domexception@1.0.0:
|
||||
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
||||
engines: {node: '>=10.5.0'}
|
||||
deprecated: Use your platform's native DOMException instead
|
||||
|
||||
node-fetch@3.3.2:
|
||||
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
node-gyp-build@4.8.4:
|
||||
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
|
||||
hasBin: true
|
||||
@ -1108,6 +1190,10 @@ packages:
|
||||
walker@1.0.8:
|
||||
resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
|
||||
|
||||
web-streams-polyfill@3.3.3:
|
||||
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
@ -1406,6 +1492,8 @@ snapshots:
|
||||
|
||||
abstract-logging@2.0.1: {}
|
||||
|
||||
agent-base@7.1.4: {}
|
||||
|
||||
ajv-formats@3.0.1(ajv@8.17.1):
|
||||
optionalDependencies:
|
||||
ajv: 8.17.1
|
||||
@ -1447,6 +1535,8 @@ snapshots:
|
||||
bindings: 1.5.0
|
||||
prebuild-install: 7.1.3
|
||||
|
||||
bignumber.js@9.3.1: {}
|
||||
|
||||
bindings@1.5.0:
|
||||
dependencies:
|
||||
file-uri-to-path: 1.0.0
|
||||
@ -1459,6 +1549,8 @@ snapshots:
|
||||
|
||||
bn.js@4.12.2: {}
|
||||
|
||||
buffer-equal-constant-time@1.0.1: {}
|
||||
|
||||
buffer@5.7.1:
|
||||
dependencies:
|
||||
base64-js: 1.5.1
|
||||
@ -1491,8 +1583,14 @@ snapshots:
|
||||
|
||||
cookie@1.0.2: {}
|
||||
|
||||
data-uri-to-buffer@4.0.1: {}
|
||||
|
||||
dateformat@4.6.3: {}
|
||||
|
||||
debug@4.4.1:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
decompress-response@6.0.0:
|
||||
dependencies:
|
||||
mimic-response: 3.1.0
|
||||
@ -1557,6 +1655,8 @@ snapshots:
|
||||
|
||||
expand-template@2.0.3: {}
|
||||
|
||||
extend@3.0.2: {}
|
||||
|
||||
fast-copy@3.0.2: {}
|
||||
|
||||
fast-decode-uri-component@1.0.1: {}
|
||||
@ -1650,6 +1750,11 @@ snapshots:
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.2
|
||||
|
||||
fetch-blob@3.2.0:
|
||||
dependencies:
|
||||
node-domexception: 1.0.0
|
||||
web-streams-polyfill: 3.3.3
|
||||
|
||||
file-uri-to-path@1.0.0: {}
|
||||
|
||||
find-my-way@9.3.0:
|
||||
@ -1662,11 +1767,31 @@ snapshots:
|
||||
dependencies:
|
||||
locate-path: 3.0.0
|
||||
|
||||
formdata-polyfill@4.0.10:
|
||||
dependencies:
|
||||
fetch-blob: 3.2.0
|
||||
|
||||
fs-constants@1.0.0: {}
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
gaxios@7.1.1:
|
||||
dependencies:
|
||||
extend: 3.0.2
|
||||
https-proxy-agent: 7.0.6
|
||||
node-fetch: 3.3.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
gcp-metadata@7.0.1:
|
||||
dependencies:
|
||||
gaxios: 7.1.1
|
||||
google-logging-utils: 1.1.1
|
||||
json-bigint: 1.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
generify@4.2.0:
|
||||
dependencies:
|
||||
isbinaryfile: 4.0.10
|
||||
@ -1676,12 +1801,40 @@ snapshots:
|
||||
|
||||
github-from-package@0.0.0: {}
|
||||
|
||||
google-auth-library@10.1.0:
|
||||
dependencies:
|
||||
base64-js: 1.5.1
|
||||
ecdsa-sig-formatter: 1.0.11
|
||||
gaxios: 7.1.1
|
||||
gcp-metadata: 7.0.1
|
||||
google-logging-utils: 1.1.1
|
||||
gtoken: 8.0.0
|
||||
jws: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
google-logging-utils@1.1.1: {}
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
gtoken@8.0.0:
|
||||
dependencies:
|
||||
gaxios: 7.1.1
|
||||
jws: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
help-me@5.0.0: {}
|
||||
|
||||
https-proxy-agent@7.0.6:
|
||||
dependencies:
|
||||
agent-base: 7.1.4
|
||||
debug: 4.4.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
ieee754@1.2.1: {}
|
||||
|
||||
inherits@2.0.4: {}
|
||||
@ -1698,12 +1851,27 @@ snapshots:
|
||||
|
||||
joycon@3.1.1: {}
|
||||
|
||||
json-bigint@1.0.0:
|
||||
dependencies:
|
||||
bignumber.js: 9.3.1
|
||||
|
||||
json-schema-ref-resolver@2.0.1:
|
||||
dependencies:
|
||||
dequal: 2.0.3
|
||||
|
||||
json-schema-traverse@1.0.0: {}
|
||||
|
||||
jwa@2.0.1:
|
||||
dependencies:
|
||||
buffer-equal-constant-time: 1.0.1
|
||||
ecdsa-sig-formatter: 1.0.11
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
jws@4.0.0:
|
||||
dependencies:
|
||||
jwa: 2.0.1
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
light-my-request@6.6.0:
|
||||
dependencies:
|
||||
cookie: 1.0.2
|
||||
@ -1788,6 +1956,8 @@ snapshots:
|
||||
dependencies:
|
||||
obliterator: 2.0.5
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
nanoid@3.3.11: {}
|
||||
|
||||
napi-build-utils@2.0.0: {}
|
||||
@ -1798,6 +1968,14 @@ snapshots:
|
||||
|
||||
node-addon-api@8.4.0: {}
|
||||
|
||||
node-domexception@1.0.0: {}
|
||||
|
||||
node-fetch@3.3.2:
|
||||
dependencies:
|
||||
data-uri-to-buffer: 4.0.1
|
||||
fetch-blob: 3.2.0
|
||||
formdata-polyfill: 4.0.10
|
||||
|
||||
node-gyp-build@4.8.4: {}
|
||||
|
||||
obliterator@2.0.5: {}
|
||||
@ -2073,6 +2251,8 @@ snapshots:
|
||||
dependencies:
|
||||
makeerror: 1.0.12
|
||||
|
||||
web-streams-polyfill@3.3.3: {}
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
xtend@4.0.2: {}
|
||||
|
@ -1,55 +1,13 @@
|
||||
import fastifyJWT from '@fastify/jwt';
|
||||
import fastifyCookie from '@fastify/cookie';
|
||||
import Database from 'better-sqlite3';
|
||||
import bcrypt from 'bcrypt';
|
||||
|
||||
const RESERVED_USERNAMES = ['admin'];
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
import { register } from './register.js';
|
||||
import { login } from './login.js';
|
||||
import authDB from '../../utils/authDB.js'
|
||||
|
||||
const saltRounds = 10;
|
||||
let database;
|
||||
|
||||
if (env === 'development') {
|
||||
database = new Database(":memory:", { verbose: console.log });
|
||||
} else {
|
||||
var dbPath = process.env.DB_PATH || '/db/db.sqlite'
|
||||
database = new Database(dbPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Can be used to prepare the database
|
||||
*/
|
||||
function prepareDB() {
|
||||
database.exec(`
|
||||
CREATE TABLE credentials (
|
||||
username TEXT PRIMARY KEY,
|
||||
passwordHash TEXT
|
||||
) STRICT
|
||||
`);
|
||||
}
|
||||
|
||||
prepareDB()
|
||||
|
||||
const userCheck = database.prepare('SELECT EXISTS (SELECT 1 FROM credentials WHERE username = ?);');
|
||||
const passwordQuery = database.prepare('SELECT passwordHash FROM credentials WHERE username = ?;');
|
||||
const userAdd = database.prepare('INSERT INTO credentials (username, passwordHash) VALUES (?, ?)');
|
||||
|
||||
/**
|
||||
* @description Can be used to check is a user exists in the database
|
||||
* @param {string} name
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function checkUser(name) {
|
||||
const result = userCheck.get(name);
|
||||
const key = Object.keys(result)[0];
|
||||
|
||||
return result[key] === 1;
|
||||
}
|
||||
|
||||
function isValidString(value) {
|
||||
return typeof value === 'string' && value.trim() !== '';
|
||||
}
|
||||
authDB.prepareDB();
|
||||
|
||||
/**
|
||||
* @param {import('fastify').FastifyInstance} fastify
|
||||
@ -67,6 +25,19 @@ export default async function(fastify, options) {
|
||||
});
|
||||
fastify.register(fastifyCookie);
|
||||
|
||||
fastify.get('/me', async (request, reply) => {
|
||||
try {
|
||||
const token = request.cookies.token;
|
||||
const decoded = await fastify.jwt.verify(token);
|
||||
return { user: decoded.user };
|
||||
} catch {
|
||||
return reply.code(401).send({ error: 'Unauthorized' });
|
||||
}
|
||||
});
|
||||
|
||||
// GOOGLE sign in
|
||||
|
||||
|
||||
fastify.post('/login', {
|
||||
schema: {
|
||||
body: {
|
||||
@ -78,44 +49,7 @@ export default async function(fastify, options) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, async (request, reply) => {
|
||||
try {
|
||||
/** @type {{ user: string, password: string }} */
|
||||
const { user, password } = request.body;
|
||||
|
||||
if (!checkUser(user) || user === 'admin') {
|
||||
return reply.code(400).send({ error: "User does not exist" });
|
||||
}
|
||||
|
||||
const query = passwordQuery.get(user);
|
||||
const hash = query?.passwordHash;
|
||||
|
||||
if (!hash) {
|
||||
return reply.code(500).send({ error: "No password was found" });
|
||||
}
|
||||
|
||||
const compare = await bcrypt.compare(password, hash);
|
||||
|
||||
if (!compare) {
|
||||
return reply.code(401).send({ error: "Incorrect password" });
|
||||
}
|
||||
|
||||
const token = fastify.jwt.sign({ user });
|
||||
|
||||
return reply
|
||||
.setCookie('token', token, {
|
||||
httpOnly: true,
|
||||
path: '/',
|
||||
secure: env !== 'development',
|
||||
sameSite: 'lax',
|
||||
})
|
||||
.code(200)
|
||||
.send({ msg: "Login successful" });
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
return reply.code(500).send({ error: "Internal server error" });
|
||||
}
|
||||
});
|
||||
}, async (request, reply) => { return login(request, reply, fastify); });
|
||||
|
||||
fastify.post('/register', {
|
||||
schema: {
|
||||
@ -128,41 +62,5 @@ export default async function(fastify, options) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, async (request, reply) => {
|
||||
try {
|
||||
/** @type {{ user: string, password: string }} */
|
||||
const { user, password } = request.body;
|
||||
|
||||
if (RESERVED_USERNAMES.includes(user)) {
|
||||
return reply.code(400).send({ error: 'Reserved username' });
|
||||
}
|
||||
|
||||
if (!isValidString(user) || !isValidString(password)) {
|
||||
return reply.code(400).send({ error: 'Invalid username or password' });
|
||||
} else if (checkUser(user) === true) {
|
||||
return reply.code(400).send({ error: "User already exist" });
|
||||
} else if (password.length <= 8) {
|
||||
return reply.code(400).send({ error: "Password too short" });
|
||||
} else if (password.length > 64) {
|
||||
return reply.code(400).send({ error: "Password too long" });
|
||||
}
|
||||
|
||||
const hash = await bcrypt.hash(password, saltRounds);
|
||||
userAdd.run(user, hash);
|
||||
return reply.code(200).send({ msg: 'Register successfuly' });
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
return reply.code(500).send({ error: "Internal server error" });
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get('/me', async (request, reply) => {
|
||||
try {
|
||||
const token = request.cookies.token;
|
||||
const decoded = await fastify.jwt.verify(token);
|
||||
return { user: decoded.user };
|
||||
} catch {
|
||||
return reply.code(401).send({ error: 'Unauthorized' });
|
||||
}
|
||||
});
|
||||
}, async (request, reply) => { return register(request, reply, saltRounds, fastify); });
|
||||
}
|
||||
|
53
src/api/auth/login.js
Normal file
53
src/api/auth/login.js
Normal file
@ -0,0 +1,53 @@
|
||||
import bcrypt from 'bcrypt';
|
||||
|
||||
import { checkUser } from '../../utils/authUtils.js';
|
||||
import authDB from '../../utils/authDB.js';
|
||||
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
|
||||
/**
|
||||
* @async
|
||||
* @param {import("fastify").FastifyRequest} request
|
||||
* @param {import("fastify").FastifyReply} reply
|
||||
* @param {import("fastify").FastifyInstance} fastify
|
||||
*
|
||||
* @returns {import('fastify').FastifyReply}
|
||||
*/
|
||||
export async function login(request, reply, fastify) {
|
||||
try {
|
||||
/** @type {{ user: string, password: string }} */
|
||||
const { user, password } = request.body;
|
||||
|
||||
if (!checkUser(user) || user === 'admin') {
|
||||
return reply.code(400).send({ error: "User does not exist" });
|
||||
}
|
||||
|
||||
const query = authDB.passwordQuery.get(user);
|
||||
const hash = query?.passwordHash;
|
||||
|
||||
if (!hash) {
|
||||
return reply.code(500).send({ error: "No password was found" });
|
||||
}
|
||||
|
||||
const compare = await bcrypt.compare(password, hash);
|
||||
|
||||
if (!compare) {
|
||||
return reply.code(401).send({ error: "Incorrect password" });
|
||||
}
|
||||
|
||||
const token = fastify.jwt.sign({ user });
|
||||
|
||||
return reply
|
||||
.setCookie('token', token, {
|
||||
httpOnly: true,
|
||||
path: '/',
|
||||
secure: env !== 'development',
|
||||
sameSite: 'lax',
|
||||
})
|
||||
.code(200)
|
||||
.send({ msg: "Login successful" });
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
return reply.code(500).send({ error: "Internal server error" });
|
||||
}
|
||||
}
|
54
src/api/auth/register.js
Normal file
54
src/api/auth/register.js
Normal file
@ -0,0 +1,54 @@
|
||||
import bcrypt from 'bcrypt';
|
||||
|
||||
import { isValidString, checkUser } from '../../utils/authUtils.js';
|
||||
import authDB from '../../utils/authDB.js';
|
||||
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
|
||||
/**
|
||||
* @async
|
||||
* @param {import("fastify").FastifyRequest} request
|
||||
* @param {import("fastify").FastifyReply} reply
|
||||
* @param {number} saltRounds
|
||||
* @param {import("fastify").FastifyInstance} fastify
|
||||
*
|
||||
* @returns {import('fastify').FastifyReply}
|
||||
*/
|
||||
export async function register(request, reply, saltRounds, fastify) {
|
||||
try {
|
||||
/** @type {{ user: string, password: string }} */
|
||||
const { user, password } = request.body;
|
||||
|
||||
if (authDB.RESERVED_USERNAMES.includes(user)) {
|
||||
return reply.code(400).send({ error: 'Reserved username' });
|
||||
}
|
||||
|
||||
if (!isValidString(user) || !isValidString(password)) {
|
||||
return reply.code(400).send({ error: 'Invalid username or password' });
|
||||
} else if (checkUser(user) === true) {
|
||||
return reply.code(400).send({ error: "User already exist" });
|
||||
} else if (password.length <= 8) {
|
||||
return reply.code(400).send({ error: "Password too short" });
|
||||
} else if (password.length > 64) {
|
||||
return reply.code(400).send({ error: "Password too long" });
|
||||
}
|
||||
|
||||
const hash = await bcrypt.hash(password, saltRounds);
|
||||
authDB.userAdd.run(user, hash);
|
||||
|
||||
const token = fastify.jwt.sign({ user });
|
||||
|
||||
return reply
|
||||
.setCookie('token', token, {
|
||||
httpOnly: true,
|
||||
path: '/',
|
||||
secure: env !== 'development',
|
||||
sameSite: 'lax',
|
||||
})
|
||||
.code(200)
|
||||
.send({ msg: 'Register successfuly' });
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
return reply.code(500).send({ error: "Internal server error" });
|
||||
}
|
||||
}
|
39
src/utils/authDB.js
Normal file
39
src/utils/authDB.js
Normal file
@ -0,0 +1,39 @@
|
||||
import Database from 'better-sqlite3';
|
||||
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
let database;
|
||||
const RESERVED_USERNAMES = ['admin'];
|
||||
let userCheck, passwordQuery, userAdd;
|
||||
|
||||
if (!env || env === 'development') {
|
||||
database = new Database(":memory:", { verbose: console.log });
|
||||
} else {
|
||||
var dbPath = process.env.DB_PATH || '/db/db.sqlite';
|
||||
database = new Database(dbPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Can be used to prepare the database
|
||||
*/
|
||||
function prepareDB() {
|
||||
database.exec(`
|
||||
CREATE TABLE IF NOT EXISTS credentials (
|
||||
username TEXT PRIMARY KEY,
|
||||
passwordHash TEXT
|
||||
) STRICT
|
||||
`);
|
||||
userCheck = database.prepare('SELECT EXISTS (SELECT 1 FROM credentials WHERE username = ?);');
|
||||
passwordQuery = database.prepare('SELECT passwordHash FROM credentials WHERE username = ?;');
|
||||
userAdd = database.prepare('INSERT INTO credentials (username, passwordHash) VALUES (?, ?)');
|
||||
}
|
||||
|
||||
|
||||
const authDB = {
|
||||
prepareDB,
|
||||
get userCheck() { return userCheck; },
|
||||
get userAdd() { return userAdd; },
|
||||
get passwordQuery() { return passwordQuery; },
|
||||
RESERVED_USERNAMES
|
||||
};
|
||||
|
||||
export default authDB;
|
23
src/utils/authUtils.js
Normal file
23
src/utils/authUtils.js
Normal file
@ -0,0 +1,23 @@
|
||||
import authDB from './authDB.js';
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isValidString(value) {
|
||||
return typeof value === 'string' && value.trim() !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {import('better-sqlite3').Statement} userCheck
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function checkUser(name, userCheck) {
|
||||
const result = authDB.userCheck.get(name);
|
||||
const key = Object.keys(result)[0];
|
||||
|
||||
return result[key] === 1;
|
||||
}
|
Reference in New Issue
Block a user