From 52761e409feb0e288348d9e4c75cc0e107b9ef9f Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 12 Jun 2025 22:05:26 +0000 Subject: [PATCH 1/4] Update dependency ejs to v3.1.10 --- yarn.lock | 88 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/yarn.lock b/yarn.lock index eb2f01c..b633577 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1148,10 +1148,10 @@ async-each@^1.0.0, async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async@0.9.x: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= +async@^3.2.3: + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== asynckit@^0.4.0: version "0.4.0" @@ -1402,9 +1402,9 @@ backo@~1.0.1: integrity sha1-2Gzk/CpQzf9rnTqXrNXJZA3k2Sc= balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base64-js@^1.0.2: version "1.3.1" @@ -1495,13 +1495,20 @@ bowser@2.9.0: integrity sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA== brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + version "1.1.12" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" + integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== + dependencies: + balanced-match "^1.0.0" + braces@^1.8.2: version "1.8.5" resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" @@ -1800,6 +1807,14 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + character-parser@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" @@ -2068,7 +2083,7 @@ color-convert@^2.0.1: color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@~1.1.4: version "1.1.4" @@ -2107,7 +2122,7 @@ compressible@^2.0.0: concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== concat-stream@^1.5.0: version "1.6.2" @@ -2711,11 +2726,11 @@ ejs@3.0.1: integrity sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw== ejs@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.3.tgz#514d967a8894084d18d3d47bd169a1c0560f093d" - integrity sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg== + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== dependencies: - jake "^10.6.1" + jake "^10.8.5" elliptic@^6.0.0: version "6.5.2" @@ -2858,7 +2873,7 @@ escape-html@^1.0.3, escape-html@~1.0.3: escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== eslint-config-airbnb-base@^14.1.0: version "14.2.0" @@ -3329,12 +3344,12 @@ file-uri-to-path@1.0.0: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== -filelist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.1.tgz#f10d1a3ae86c1694808e8f20906f43d4c9132dbb" - integrity sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ== +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== dependencies: - minimatch "^3.0.4" + minimatch "^5.0.1" filename-regex@^2.0.0: version "2.0.1" @@ -3804,7 +3819,7 @@ has-ansi@^2.0.0: has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" @@ -4573,15 +4588,15 @@ iterate-value@^1.0.0: es-get-iterator "^1.0.2" iterate-iterator "^1.0.1" -jake@^10.6.1: - version "10.8.1" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.1.tgz#0f6f5ef13ebe014104527fb4b1b24f44cd1f04d6" - integrity sha512-eSp5h9S7UFzKdQERTyF+KuPLjDZa1Tbw8gCVUn98n4PbIkLEDGe4zl7vF4Qge9kQj06HcymnksPk8jznPZeKsA== +jake@^10.8.5: + version "10.9.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" + integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA== dependencies: - async "0.9.x" - chalk "^2.4.2" - filelist "^1.0.1" - minimatch "^3.0.4" + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" jimp@^0.13.0: version "0.13.0" @@ -5326,20 +5341,27 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" From 677dfe25afe72c295962b9623710d24c7bc75ae1 Mon Sep 17 00:00:00 2001 From: Jonathan Cremin Date: Fri, 13 Jun 2025 09:32:37 +0100 Subject: [PATCH 2/4] Fix tests, run against ci --- .envrc.example | 25 +++++++ .forgejo/workflows/build-image.yml | 40 ---------- .forgejo/workflows/ci.yml | 85 ++++++++++++++++++++++ .gitignore | 3 +- Makefile | 22 +++--- web/lib/auth.js | 113 +++++++++++++---------------- 6 files changed, 175 insertions(+), 113 deletions(-) create mode 100644 .envrc.example delete mode 100644 .forgejo/workflows/build-image.yml create mode 100644 .forgejo/workflows/ci.yml diff --git a/.envrc.example b/.envrc.example new file mode 100644 index 0000000..ce12b2f --- /dev/null +++ b/.envrc.example @@ -0,0 +1,25 @@ +export DEBUG="hostr*" + +export NODE_ENV=development +export PORT=4040 +export WEB_BASE_URL=http://localhost:$PORT +export API_BASE_URL=$WEB_BASE_URL/api +export UPLOAD_STORAGE_PATH=$HOME/.hostr/uploads +export COOKIE_KEY=INSECURE +export EMAIL_FROM= +export EMAIL_NAME= + +export STATSD_HOST=localhost +export DATABASE_URL=postgresql://hostr:hostr@database:5432/hostr +export REDIS_URL=redis://localhost:6379 +export SENDGRID_KEY= +export STRIPE_SECRET_KEY= +export STRIPE_PUBLIC_KEY= + +# optional, some functionality will be disabled +export AWS_ENDPOINT= # only for AWS-like providers, not AWS +export AWS_ACCESS_KEY_ID= +export AWS_SECRET_ACCESS_KEY= +export AWS_BUCKET= +export VIRUSTOTAL_KEY= +export SENTRY_DSN= diff --git a/.forgejo/workflows/build-image.yml b/.forgejo/workflows/build-image.yml deleted file mode 100644 index 82fa8f7..0000000 --- a/.forgejo/workflows/build-image.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: ci - -on: - push: - branches: main - pull_request: - types: [opened, synchronize, reopened] -jobs: - build-image: - runs-on: self-hosted - steps: - - name: Set current date as env variable - run: echo "NOW=$(date +'%Y%m%d-%H%M%S')" >> $GITHUB_ENV - - name: Fix for bad os check - run: echo "RUNNER_OS=Linux" >> $GITHUB_ENV - - name: Login to Forgejo Registry - uses: https://cremin.dev/actions/podman-login@v1 - with: - registry: cremin.dev - username: ${{ github.actor }} - password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} - - name: Check out repository - uses: https://cremin.dev/actions/checkout@v4 - - name: Build image - uses: https://cremin.dev/actions/buildah-build@v2 - with: - containerfiles: ./Containerfile - context: ./ - oci: true - layers: true - image: hostr - tags: latest ${{ github.sha }} - - name: Push image - uses: https://cremin.dev/actions/push-to-registry@v2 - with: - registry: cremin.dev/jonathan - username: ${{ github.actor }} - password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} - image: hostr - tags: latest ${{ github.sha }} diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..61d221e --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,85 @@ +name: ci + +on: + push: + branches: [main] + pull_request: + types: [opened, synchronize, reopened] + +services: + database: + image: postgres:10-alpine + env: + POSTGRES_PASSWORD: hostr + POSTGRES_USER: hostr + POSTGRES_DB: hostr + ports: + - 5432:5432 + redis: + image: redis:4.0.2-alpine + ports: + - 6379:6379 + minio: + image: minio/minio + env: + MINIO_ACCESS_KEY: 7HYV3KPRGQ8Z5YCDNWC6 + MINIO_SECRET_KEY: 0kWP/ZkgIwQzgL9t4SGv9Uc93rO//OdyqMH329b/ + ports: + - 9000:9000 + cmd: server /export + +jobs: + build-image: + runs-on: self-hosted + steps: + - name: Set current date as env variable + run: echo "NOW=$(date +'%Y%m%d-%H%M%S')" >> $GITHUB_ENV + - name: Fix for bad os check + run: echo "RUNNER_OS=Linux" >> $GITHUB_ENV + - name: Login to Forgejo Registry + uses: https://cremin.dev/actions/podman-login@v1 + with: + registry: cremin.dev + username: ${{ github.actor }} + password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} + - name: Check out repository + uses: https://cremin.dev/actions/checkout@v4 + - name: Build image + uses: https://cremin.dev/actions/buildah-build@v2 + with: + containerfiles: ./Containerfile + context: ./ + oci: true + layers: true + image: hostr + tags: latest ${{ github.sha }} + - name: Push image + uses: https://cremin.dev/actions/push-to-registry@v2 + with: + registry: cremin.dev/jonathan + username: ${{ github.actor }} + password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} + image: hostr + tags: latest ${{ github.sha }} + test-image: + runs-on: self-hosted + needs: build-image + steps: + - name: Check out repository + uses: https://cremin.dev/actions/checkout@v4 + - name: Test image + env: + WEB_BASE_URL: http://localhost:3000 + API_BASE_URL: http://localhost:3000/api + UPLOAD_STORAGE_PATH: /hostr/uploads + COOKIE_KEY: TESTING + EMAIL_FROM: jonathan@hostr.co + EMAIL_NAME: "Jonathan from Hostr" + DATABASE_URL: postgresql://hostr:hostr@database:5432/hostr + REDIS_URL: redis://redis:6379 + AWS_ENDPOINT: http://minio:9000 + AWS_ACCESS_KEY_ID: 7HYV3KPRGQ8Z5YCDNWC6 + AWS_SECRET_ACCESS_KEY: 0kWP/ZkgIwQzgL9t4SGv9Uc93rO//OdyqMH329b/ + AWS_BUCKET: hostr + run: | + podman run --rm --env-host -it cremin.dev/jonathan/hostr:${{ github.sha }} yarn test diff --git a/.gitignore b/.gitignore index 064a275..9bebce6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -.env* +.envrc .DS_Store .sass-cache/ node_modules @@ -7,6 +7,7 @@ jspm_packages npm-debug.log web/public/build web/public/styles/*.css +web/public/styles/*.css.map *.gz minigun*.json test*.json diff --git a/Makefile b/Makefile index 65974ab..67a7951 100644 --- a/Makefile +++ b/Makefile @@ -10,36 +10,36 @@ help: .PHONY: build build: ## Run `yarn run build` - docker-compose run --rm app yarn run build + podman compose run --rm app yarn run build .PHONY: test test: ## Run tests - docker-compose run --rm app yarn test + podman compose run --rm app yarn test .PHONY: logs logs: ## Tail the app and worker logs - docker-compose logs -f app worker + podman compose logs -f app worker .PHONY: migrate migrate: ## Migrate database schema - docker-compose run --rm app yarn run initdb + podman compose run --rm app yarn run initdb .PHONY: init init: ## Migrate database schema - docker-compose run --rm app yarn run init + podman compose run --rm app yarn run init .PHONY: watch-frontend watch-frontend: ## Build and watch for changes - docker-compose run --rm app yarn run watch + podman compose run --rm app yarn run watch -.PHONY: docker-compose-up -docker-compose-up: ## Start (and create) docker containers - docker-compose up -d +.PHONY: podman compose-up +podman compose-up: ## Start (and create) docker containers + podman compose up -d .PHONY: yarn yarn: ## Update yarn dependencies - docker-compose run --rm app yarn + podman compose run --rm app yarn .PHONY: shell shell: ## Run shell - docker-compose run --rm app sh + podman compose run --rm app sh diff --git a/web/lib/auth.js b/web/lib/auth.js index 45165b9..bbba83c 100644 --- a/web/lib/auth.js +++ b/web/lib/auth.js @@ -1,29 +1,29 @@ -import crypto from 'crypto'; -import { join } from 'path'; -import passwords from 'passwords'; -import uuid from 'node-uuid'; -import views from 'co-views'; -import debugname from 'debug'; -import sendgrid from '@sendgrid/mail'; -import models from '../../models'; +import crypto from "crypto"; +import { join } from "path"; +import passwords from "passwords"; +import uuid from "node-uuid"; +import views from "co-views"; +import debugname from "debug"; +import sendgrid from "@sendgrid/mail"; +import models from "../../models"; -const render = views(join(__dirname, '..', 'views'), { default: 'ejs' }); -const debug = debugname('hostr-web:auth'); +const render = views(join(__dirname, "..", "views"), { default: "ejs" }); +const debug = debugname("hostr-web:auth"); sendgrid.setApiKey(process.env.SENDGRID_KEY); const from = process.env.EMAIL_FROM; const fromname = process.env.EMAIL_NAME; export async function authenticate(email, password) { - const remoteIp = this.headers['x-forwarded-for'] || this.ip; + const remoteIp = this.headers["x-forwarded-for"] || this.ip; if (!password || password.length < 6) { - debug('No password, or password too short'); - return new Error('Invalid login details'); + debug("No password, or password too short"); + return new Error("Invalid login details"); } const count = await models.login.count({ where: { - ip: remoteIp.split(',')[0], + ip: remoteIp.split(",")[0], successful: false, createdAt: { $gt: Math.ceil(Date.now()) - 600000, @@ -32,8 +32,8 @@ export async function authenticate(email, password) { }); if (count > 25) { - debug('Throttling brute force'); - return new Error('Invalid login details'); + debug("Throttling brute force"); + return new Error("Invalid login details"); } const user = await models.user.findOne({ where: { @@ -43,30 +43,29 @@ export async function authenticate(email, password) { }); const login = await models.login.create({ - ip: remoteIp.split(',')[0], + ip: remoteIp.split(",")[0], successful: false, }); if (user && user.password) { login.userId = user.id; if (await passwords.verify(password, user.password)) { - debug('Password verified'); + debug("Password verified"); login.successful = true; await login.save(); return user; } - debug('Password invalid'); + debug("Password invalid"); } await login.save(); return false; } - export async function setupSession(user) { - debug('Setting up session'); + debug("Setting up session"); const token = uuid.v4(); - debug(user) - await this.redis.set(token, user.id, 'EX', 604800); + + await this.redis.set(token, user.id, "EX", 604800); const sessionUser = { id: user.id, @@ -76,27 +75,26 @@ export async function setupSession(user) { joined: user.createdAt, plan: user.plan, uploadsToday: await models.file.count({ userId: user.id }), - md5: crypto.createHash('md5').update(user.email).digest('hex'), + md5: crypto.createHash("md5").update(user.email).digest("hex"), token, }; - if (sessionUser.plan === 'Pro') { + if (sessionUser.plan === "Pro") { sessionUser.maxFileSize = 524288000; - sessionUser.dailyUploadAllowance = 'unlimited'; + sessionUser.dailyUploadAllowance = "unlimited"; } this.session.user = sessionUser; - if (this.request.body.remember && this.request.body.remember === 'on') { + if (this.request.body.remember && this.request.body.remember === "on") { const remember = await models.remember.create({ id: uuid(), userId: user.id, }); - this.cookies.set('r', remember.id, { maxAge: 1209600000, httpOnly: true }); + this.cookies.set("r", remember.id, { maxAge: 1209600000, httpOnly: true }); } - debug('Session set up'); + debug("Session set up"); } - export async function signup(email, password, ip) { const existingUser = await models.user.findOne({ where: { @@ -105,26 +103,29 @@ export async function signup(email, password, ip) { }, }); if (existingUser) { - debug('Email already in use.'); - throw new Error('Email already in use.'); + debug("Email already in use."); + throw new Error("Email already in use."); } const cryptedPassword = await passwords.crypt(password); - const user = await models.user.create({ - email, - password: cryptedPassword, - ip, - plan: 'Free', - activation: { - id: uuid(), + const user = await models.user.create( + { email, + password: cryptedPassword, + ip, + plan: "Free", + activation: { + id: uuid(), + email, + }, }, - }, { - include: [models.activation], - }); + { + include: [models.activation], + }, + ); await user.save(); - const html = await render('email/inlined/activate', { + const html = await render("email/inlined/activate", { activationUrl: `${process.env.WEB_BASE_URL}/activate/${user.activation.id}`, }); const text = `Thanks for signing up to Hostr! @@ -136,18 +137,15 @@ ${process.env.WEB_BASE_URL}/activate/${user.activation.id} `; sendgrid.send({ to: user.email, - subject: 'Welcome to Hostr', + subject: "Welcome to Hostr", from, fromname, html, text, - categories: [ - 'activate', - ], + categories: ["activate"], }); } - export async function sendResetToken(email) { const user = await models.user.findOne({ where: { @@ -159,7 +157,7 @@ export async function sendResetToken(email) { id: uuid.v4(), userId: user.id, }); - const html = await render('email/inlined/forgot', { + const html = await render("email/inlined/forgot", { forgotUrl: `${process.env.WEB_BASE_URL}/forgot/${reset.id}`, }); const text = `It seems you've forgotten your password :( @@ -167,38 +165,32 @@ Visit ${process.env.WEB_BASE_URL}/forgot/${reset.id} to set a new one. `; sendgrid.send({ to: user.email, - from: 'jonathan@hostr.co', - fromname: 'Jonathan from Hostr', - subject: 'Hostr Password Reset', + from: "jonathan@hostr.co", + fromname: "Jonathan from Hostr", + subject: "Hostr Password Reset", html, text, - categories: [ - 'password-reset', - ], + categories: ["password-reset"], }); } else { - throw new Error('There was an error looking up your email address.'); + throw new Error("There was an error looking up your email address."); } } - export async function fromToken(token) { const userId = await this.redis.get(token); return models.user.findByPk(userId); } - export async function fromCookie(rememberId) { const userId = await models.remember.findByPk(rememberId); return models.user.findByPk(userId); } - export async function validateResetToken(resetId) { return models.reset.findByPk(resetId); } - export async function updatePassword(userId, password) { const cryptedPassword = await passwords.crypt(password); const user = await models.user.findByPk(userId); @@ -206,7 +198,6 @@ export async function updatePassword(userId, password) { await user.save(); } - export async function activateUser(code) { const activation = await models.activation.findOne({ where: { From 36e91ff03eb696bca09f70e8f342af6aa7f92517 Mon Sep 17 00:00:00 2001 From: Jonathan Cremin Date: Fri, 13 Jun 2025 09:41:37 +0100 Subject: [PATCH 3/4] Update services hosts --- .forgejo/workflows/ci.yml | 44 +++++++++++++++++---------------------- docker-compose.yml | 4 ++-- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 61d221e..a76d0c2 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -6,28 +6,6 @@ on: pull_request: types: [opened, synchronize, reopened] -services: - database: - image: postgres:10-alpine - env: - POSTGRES_PASSWORD: hostr - POSTGRES_USER: hostr - POSTGRES_DB: hostr - ports: - - 5432:5432 - redis: - image: redis:4.0.2-alpine - ports: - - 6379:6379 - minio: - image: minio/minio - env: - MINIO_ACCESS_KEY: 7HYV3KPRGQ8Z5YCDNWC6 - MINIO_SECRET_KEY: 0kWP/ZkgIwQzgL9t4SGv9Uc93rO//OdyqMH329b/ - ports: - - 9000:9000 - cmd: server /export - jobs: build-image: runs-on: self-hosted @@ -42,6 +20,7 @@ jobs: registry: cremin.dev username: ${{ github.actor }} password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} + logout: false - name: Check out repository uses: https://cremin.dev/actions/checkout@v4 - name: Build image @@ -51,19 +30,34 @@ jobs: context: ./ oci: true layers: true - image: hostr + image: cremin.dev/jonathan/hostr tags: latest ${{ github.sha }} - name: Push image uses: https://cremin.dev/actions/push-to-registry@v2 with: - registry: cremin.dev/jonathan + registry: cremin.dev username: ${{ github.actor }} password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} - image: hostr + image: jonathan/hostr tags: latest ${{ github.sha }} test-image: runs-on: self-hosted needs: build-image + services: + database: + image: postgres:14-alpine + env: + POSTGRES_PASSWORD: hostr + POSTGRES_USER: hostr + POSTGRES_DB: hostr + redis: + image: redis:4.0.2-alpine + minio: + image: minio/minio + env: + MINIO_ACCESS_KEY: 7HYV3KPRGQ8Z5YCDNWC6 + MINIO_SECRET_KEY: 0kWP/ZkgIwQzgL9t4SGv9Uc93rO//OdyqMH329b/ + cmd: ["server", "/export"] steps: - name: Check out repository uses: https://cremin.dev/actions/checkout@v4 diff --git a/docker-compose.yml b/docker-compose.yml index fe33cd8..d36dff3 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -61,7 +61,7 @@ services: - "3001:3000" command: yarn run worker database: - image: "postgres:10-alpine" + image: "postgres:14-alpine" ports: - "5432:5432" environment: @@ -69,7 +69,7 @@ services: POSTGRES_USER: "hostr" POSTGRES_DB: "hostr" redis: - image: "redis:4.0.2-alpine" + image: "redis:8-alpine" ports: - "6379:6379" minio: From ab01290b72fc0036d076573ce6222560ebfda40b Mon Sep 17 00:00:00 2001 From: Jonathan Cremin Date: Sun, 15 Jun 2025 19:03:03 +0100 Subject: [PATCH 4/4] Use Docker instead of Podman for now --- .forgejo/workflows/.env | 12 +++++++++++ .forgejo/workflows/ci.yml | 44 ++++++++++----------------------------- 2 files changed, 23 insertions(+), 33 deletions(-) create mode 100644 .forgejo/workflows/.env diff --git a/.forgejo/workflows/.env b/.forgejo/workflows/.env new file mode 100644 index 0000000..0c2f98d --- /dev/null +++ b/.forgejo/workflows/.env @@ -0,0 +1,12 @@ +WEB_BASE_URL=http://localhost:3000 +API_BASE_URL=http://localhost:3000/api +UPLOAD_STORAGE_PATH=/hostr/uploads +COOKIE_KEY=TESTING +EMAIL_FROM=jonathan@hostr.co +EMAIL_NAME="Jonathan from Hostr" +DATABASE_URL=postgresql://hostr:hostr@database:5432/hostr +REDIS_URL=redis://redis:6379 +AWS_ENDPOINT=http://minio:9000 +AWS_ACCESS_KEY_ID=7HYV3KPRGQ8Z5YCDNWC6 +AWS_SECRET_ACCESS_KEY=0kWP/ZkgIwQzgL9t4SGv9Uc93rO//OdyqMH329b/ +AWS_BUCKET=hostr diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index a76d0c2..b1c0994 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -14,34 +14,25 @@ jobs: run: echo "NOW=$(date +'%Y%m%d-%H%M%S')" >> $GITHUB_ENV - name: Fix for bad os check run: echo "RUNNER_OS=Linux" >> $GITHUB_ENV - - name: Login to Forgejo Registry - uses: https://cremin.dev/actions/podman-login@v1 + - name: Login to Docker Hub + uses: https://cremin.dev/actions/docker-login@v3 with: registry: cremin.dev username: ${{ github.actor }} password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} - logout: false - name: Check out repository uses: https://cremin.dev/actions/checkout@v4 - - name: Build image - uses: https://cremin.dev/actions/buildah-build@v2 + - name: Set up Docker Buildx + uses: https://cremin.dev/actions/docker-setup-buildx@v3 + - name: Build and push + uses: https://cremin.dev/actions/docker-build-push@v6 with: - containerfiles: ./Containerfile + file: ./Containerfile context: ./ - oci: true - layers: true - image: cremin.dev/jonathan/hostr - tags: latest ${{ github.sha }} - - name: Push image - uses: https://cremin.dev/actions/push-to-registry@v2 - with: - registry: cremin.dev - username: ${{ github.actor }} - password: ${{ secrets.FORGEJO_REGISTRY_TOKEN }} - image: jonathan/hostr - tags: latest ${{ github.sha }} + tags: cremin.dev/jonathan/hostr:latest,cremin.dev/jonathan/hostr:${{ github.sha }} + push: true test-image: - runs-on: self-hosted + runs-on: node22 needs: build-image services: database: @@ -62,18 +53,5 @@ jobs: - name: Check out repository uses: https://cremin.dev/actions/checkout@v4 - name: Test image - env: - WEB_BASE_URL: http://localhost:3000 - API_BASE_URL: http://localhost:3000/api - UPLOAD_STORAGE_PATH: /hostr/uploads - COOKIE_KEY: TESTING - EMAIL_FROM: jonathan@hostr.co - EMAIL_NAME: "Jonathan from Hostr" - DATABASE_URL: postgresql://hostr:hostr@database:5432/hostr - REDIS_URL: redis://redis:6379 - AWS_ENDPOINT: http://minio:9000 - AWS_ACCESS_KEY_ID: 7HYV3KPRGQ8Z5YCDNWC6 - AWS_SECRET_ACCESS_KEY: 0kWP/ZkgIwQzgL9t4SGv9Uc93rO//OdyqMH329b/ - AWS_BUCKET: hostr run: | - podman run --rm --env-host -it cremin.dev/jonathan/hostr:${{ github.sha }} yarn test + docker run --env-file ./.forgejo/workflows/.env --rm -it cremin.dev/jonathan/hostr:${{ github.sha }} yarn test