Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
4aa9877496 chore(deps): bump node-forge and @parse/node-apn
Bumps [node-forge](https://github.com/digitalbazaar/forge) to 1.3.2 and updates ancestor dependency [@parse/node-apn](https://github.com/parse-community/node-apn). These dependencies need to be updated together.


Updates `node-forge` from 1.3.1 to 1.3.2
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2)

Updates `@parse/node-apn` from 5.2.3 to 7.0.0
- [Release notes](https://github.com/parse-community/node-apn/releases)
- [Changelog](https://github.com/parse-community/node-apn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/parse-community/node-apn/compare/5.2.3...7.0.0)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-version: 1.3.2
  dependency-type: indirect
- dependency-name: "@parse/node-apn"
  dependency-version: 7.0.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-03 22:43:56 +00:00
17 changed files with 3811 additions and 5220 deletions

View File

@@ -135,7 +135,7 @@ jobs:
strategy: strategy:
matrix: matrix:
node-version: [21.x] node-version: [21.x]
mongodb-version: [7.0] mongodb-version: [4.2]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@@ -144,13 +144,11 @@ jobs:
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set - name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
uses: supercharge/mongodb-github-action@1.11.0 uses: supercharge/mongodb-github-action@1.3.0
with: with:
mongodb-version: ${{ matrix.mongodb-version }} mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs mongodb-replica-set: rs
- run: sudo apt update - run: sudo apt update
- run: sudo apt -y install libkrb5-dev - run: sudo apt -y install libkrb5-dev
- run: cp config.json.example config.json - run: cp config.json.example config.json
@@ -160,17 +158,15 @@ jobs:
env: env:
CI: true CI: true
NODE_ENV: test NODE_ENV: test
- run: npm run test:api:unit - run: npm run test:api:unit
env: env:
REQUIRES_SERVER=true: true REQUIRES_SERVER=true: true
api-v3-integration: api-v3-integration:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [21.x] node-version: [21.x]
mongodb-version: [7.0] mongodb-version: [4.2]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@@ -180,11 +176,10 @@ jobs:
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set - name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
uses: supercharge/mongodb-github-action@1.11.0 uses: supercharge/mongodb-github-action@1.3.0
with: with:
mongodb-version: ${{ matrix.mongodb-version }} mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs mongodb-replica-set: rs
- run: sudo apt update - run: sudo apt update
- run: sudo apt -y install libkrb5-dev - run: sudo apt -y install libkrb5-dev
- run: cp config.json.example config.json - run: cp config.json.example config.json
@@ -194,18 +189,15 @@ jobs:
env: env:
CI: true CI: true
NODE_ENV: test NODE_ENV: test
- run: npm run test:api-v3:integration - run: npm run test:api-v3:integration
env: env:
REQUIRES_SERVER=true: true REQUIRES_SERVER=true: true
api-v4-integration: api-v4-integration:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [21.x] node-version: [21.x]
mongodb-version: [7.0] mongodb-version: [4.2]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@@ -215,11 +207,10 @@ jobs:
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set - name: Start MongoDB ${{ matrix.mongodb-version }} Replica Set
uses: supercharge/mongodb-github-action@1.11.0 uses: supercharge/mongodb-github-action@1.3.0
with: with:
mongodb-version: ${{ matrix.mongodb-version }} mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs mongodb-replica-set: rs
- run: sudo apt update - run: sudo apt update
- run: sudo apt -y install libkrb5-dev - run: sudo apt -y install libkrb5-dev
- run: cp config.json.example config.json - run: cp config.json.example config.json
@@ -229,7 +220,6 @@ jobs:
env: env:
CI: true CI: true
NODE_ENV: test NODE_ENV: test
- run: npm run test:api-v4:integration - run: npm run test:api-v4:integration
env: env:
REQUIRES_SERVER=true: true REQUIRES_SERVER=true: true

2
.gitignore vendored
View File

@@ -47,5 +47,5 @@ webpack.webstorm.config
# mongodb replica set for local dev # mongodb replica set for local dev
mongodb-*.tgz mongodb-*.tgz
/mongodb-* /mongodb-data*
/.nyc_output /.nyc_output

53
docker-compose.dev.yml Normal file
View File

@@ -0,0 +1,53 @@
services:
client:
build:
context: .
dockerfile: ./Dockerfile-Dev
command: ["npm", "run", "client:dev"]
depends_on:
- server
environment:
- BASE_URL=http://server:3000
networks:
- habitica
ports:
- "8080:8080"
volumes:
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
- /usr/src/habitica/website/client/node_modules
server:
build:
context: .
dockerfile: ./Dockerfile-Dev
command: ["npm", "start"]
depends_on:
mongo:
condition: service_healthy
environment:
- NODE_DB_URI=mongodb://mongo/habitrpg
networks:
- habitica
ports:
- "3000:3000"
volumes:
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
mongo:
image: mongo:5.0.23
restart: unless-stopped
command: ["--replSet", "rs", "--bind_ip_all", "--port", "27017"]
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet
interval: 10s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
networks:
- habitica
ports:
- "27017:27017"
networks:
habitica:
driver: bridge

View File

@@ -1,24 +0,0 @@
networks:
mongodb-network:
name: "mongodb-network"
driver: bridge
services:
mongodb:
image: "mongo:7.0"
container_name: "habitica-mongodb-only"
networks:
- mongodb-network
hostname: "mongodb"
ports:
- "27017:27017"
restart: "unless-stopped"
volumes:
- "./mongodb-data-docker:/data/db"
entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs" ]
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet
interval: 10s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30

View File

@@ -1,24 +0,0 @@
networks:
mongodb-network:
name: "mongodb-network"
driver: bridge
services:
mongodb:
image: "mongo:7.0"
container_name: "habitica-mongodb-test"
networks:
- mongodb-network
hostname: "mongodb"
ports:
- "27017:27017"
restart: "unless-stopped"
volumes:
- "./mongodb-data-docker-testing:/data/db"
entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs" ]
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet
interval: 10s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30

View File

@@ -1,57 +1,35 @@
version: "3"
services: services:
client: client:
build: build: .
context: . networks:
dockerfile: ./Dockerfile-Dev - habitica
command: ["npm", "run", "client:dev:docker"]
depends_on:
- server
environment: environment:
- BASE_URL=http://server:3000 - BASE_URL=http://server:3000
networks:
- habitica
ports: ports:
- "5173:5173" - "8080:8080"
volumes: command: ["npm", "run", "client:dev"]
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
- /usr/src/habitica/website/client/node_modules
server:
build:
context: .
dockerfile: ./Dockerfile-Dev
command: ["npm", "start"]
depends_on: depends_on:
mongo: - server
condition: service_healthy
environment: server:
- NODE_DB_URI=mongodb://mongo/habitrpg build: .
networks:
- habitica
ports: ports:
- "3000:3000" - "3000:3000"
volumes:
- .:/usr/src/habitica
- /usr/src/habitica/node_modules
mongo:
image: "mongo:7.0"
container_name: "habitica-mongodb"
networks: networks:
- habitica - habitica
hostname: "mongodb" environment:
- NODE_DB_URI=mongodb://mongo/habitrpg
depends_on:
- mongo
mongo:
image: mongo:3.6
ports: ports:
- "27017:27017" - "27017:27017"
restart: "unless-stopped" networks:
volumes: - habitica
- "./mongodb-data-docker:/data/db"
entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs" ]
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet
interval: 10s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
networks: networks:
habitica: habitica:

View File

@@ -5,7 +5,7 @@ import path from 'path';
import babel from 'gulp-babel'; import babel from 'gulp-babel';
import os from 'os'; import os from 'os';
import fs from 'fs'; import fs from 'fs';
import spawn from 'cross-spawn'; import spawn from 'cross-spawn'; // eslint-disable-line import/no-extraneous-dependencies
import clean from 'rimraf'; import clean from 'rimraf';
gulp.task('build:babel:server', () => gulp.src('website/server/**/*.js') gulp.task('build:babel:server', () => gulp.src('website/server/**/*.js')
@@ -35,7 +35,7 @@ gulp.task('build:prod', gulp.series(
// When used on windows `run-rs` must first be run without the `--keep` option // When used on windows `run-rs` must first be run without the `--keep` option
// in order to be setup correctly, afterwards it can be used. // in order to be setup correctly, afterwards it can be used.
const MONGO_PATH = path.join(__dirname, '/../mongodb-data-docker/'); const MONGO_PATH = path.join(__dirname, '/../mongodb-data/');
gulp.task('build:prepare-mongo', async () => { gulp.task('build:prepare-mongo', async () => {
if (fs.existsSync(MONGO_PATH)) { if (fs.existsSync(MONGO_PATH)) {
@@ -51,32 +51,29 @@ gulp.task('build:prepare-mongo', async () => {
console.log('MongoDB data folder is missing, setting up.'); // eslint-disable-line no-console console.log('MongoDB data folder is missing, setting up.'); // eslint-disable-line no-console
// use run-rs without --keep, kill it as soon as the replica set starts // use run-rs without --keep, kill it as soon as the replica set starts
const dockerMongoProcess = spawn('npm', ['run', 'docker:mongo:dev']); const runRsProcess = spawn('run-rs', ['-v', '4.1.1', '-l', 'ubuntu1804', '--dbpath', 'mongodb-data', '--number', '1', '--quiet']);
let manuallyStopped = false; for await (const chunk of runRsProcess.stdout) {
for await (const chunk of dockerMongoProcess.stdout) {
const stringChunk = chunk.toString(); const stringChunk = chunk.toString();
console.log(stringChunk); // eslint-disable-line no-console console.log(stringChunk); // eslint-disable-line no-console
// kills the process after the replica set is setup // kills the process after the replica set is setup
if (stringChunk.includes('mongod startup complete')) { if (stringChunk.includes('Started replica set')) {
console.log('MongoDB setup correctly.'); // eslint-disable-line no-console console.log('MongoDB setup correctly.'); // eslint-disable-line no-console
dockerMongoProcess.kill(); runRsProcess.kill();
manuallyStopped = true;
} }
} }
let error = ''; let error = '';
for await (const chunk of dockerMongoProcess.stderr) { for await (const chunk of runRsProcess.stderr) {
const stringChunk = chunk.toString(); const stringChunk = chunk.toString();
error += stringChunk; error += stringChunk;
} }
const exitCode = await new Promise(resolve => { const exitCode = await new Promise(resolve => {
dockerMongoProcess.on('close', resolve); runRsProcess.on('close', resolve);
}); });
if (!manuallyStopped && (exitCode || error.length > 0)) { if (exitCode || error.length > 0) {
// remove any leftover files // remove any leftover files
clean.sync(MONGO_PATH); clean.sync(MONGO_PATH);

View File

@@ -53,11 +53,6 @@ gulp.task('test:prepare:mongo', cb => {
const mongooseOptions = getDefaultConnectionOptions(); const mongooseOptions = getDefaultConnectionOptions();
const connectionUrl = getDevelopmentConnectionUrl(TEST_DB_URI); const connectionUrl = getDevelopmentConnectionUrl(TEST_DB_URI);
console.info({
mongooseOptions,
connectionUrl,
});
mongoose.connect(connectionUrl, mongooseOptions) mongoose.connect(connectionUrl, mongooseOptions)
.then(() => mongoose.connection.dropDatabase()) .then(() => mongoose.connection.dropDatabase())
.then(() => mongoose.connection.close()).then(() => { .then(() => mongoose.connection.close()).then(() => {

1114
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,14 @@
{ {
"name": "habitica", "name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.", "description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "5.42.2", "version": "5.42.1",
"main": "./website/server/index.js", "main": "./website/server/index.js",
"dependencies": { "dependencies": {
"@babel/core": "^7.22.10", "@babel/core": "^7.22.10",
"@babel/preset-env": "^7.22.10", "@babel/preset-env": "^7.22.10",
"@babel/register": "^7.22.15", "@babel/register": "^7.22.15",
"@google-cloud/trace-agent": "^7.1.2", "@google-cloud/trace-agent": "^7.1.2",
"@parse/node-apn": "^5.2.3", "@parse/node-apn": "^7.0.0",
"@slack/webhook": "^6.1.0", "@slack/webhook": "^6.1.0",
"accepts": "^1.3.8", "accepts": "^1.3.8",
"amazon-payments": "^0.2.9", "amazon-payments": "^0.2.9",
@@ -100,17 +100,13 @@
"coverage": "nyc report --reporter=html --report-dir coverage/results; open coverage/results/index.html", "coverage": "nyc report --reporter=html --report-dir coverage/results; open coverage/results/index.html",
"sprites": "gulp sprites:compile", "sprites": "gulp sprites:compile",
"client:dev": "cd website/client && npm run serve", "client:dev": "cd website/client && npm run serve",
"client:dev:docker": "cd website/client && npm run serve:docker",
"client:build": "cd website/client && npm run build", "client:build": "cd website/client && npm run build",
"client:unit": "cd website/client && npm run test:unit", "client:unit": "cd website/client && npm run test:unit",
"start": "node --watch ./website/server/index.js", "start": "node --watch ./website/server/index.js",
"start:simple": "node ./website/server/index.js", "start:simple": "node ./website/server/index.js",
"debug": "node --watch --inspect ./website/server/index.js", "debug": "node --watch --inspect ./website/server/index.js",
"docker:aio": "docker compose -f docker-compose.yml up", "mongo:dev": "run-rs -v 7.0.23 -l ubuntu2214 --keep --dbpath mongodb-data --number 1 --quiet",
"docker:mongo:dev": "docker compose -f docker-compose.mongo-only.yml up", "mongo:test": "run-rs -v 7.0.23 -l ubuntu2214 --keep --dbpath mongodb-data-testing --number 1 --quiet",
"docker:mongo:dev:down": "docker compose -f docker-compose.mongo-only.yml down",
"docker:mongo:test": "docker compose -f docker-compose.mongo-test-local.yml up",
"mongo:test": "node scripts/start-local-mongo.mjs --test-db",
"postinstall": "git config --global url.\"https://\".insteadOf git:// && gulp build && cd website/client && npm install", "postinstall": "git config --global url.\"https://\".insteadOf git:// && gulp build && cd website/client && npm install",
"apidoc": "gulp apidoc", "apidoc": "gulp apidoc",
"heroku-postbuild": ".heroku/report_deploy.sh" "heroku-postbuild": ".heroku/report_deploy.sh"
@@ -126,6 +122,7 @@
"monk": "^7.3.4", "monk": "^7.3.4",
"nyc": "^15.1.0", "nyc": "^15.1.0",
"require-again": "^2.0.0", "require-again": "^2.0.0",
"run-rs": "^0.7.7",
"sinon-chai": "^3.7.0", "sinon-chai": "^3.7.0",
"sinon-stub-promise": "^4.0.0" "sinon-stub-promise": "^4.0.0"
} }

View File

@@ -21,7 +21,6 @@ export async function getProperty (collectionName, id, path) {
// Specifically helpful for the GET /groups tests, // Specifically helpful for the GET /groups tests,
// resets the db to an empty state and creates a tavern document // resets the db to an empty state and creates a tavern document
export async function resetHabiticaDB () { export async function resetHabiticaDB () {
console.info('Resetting Habitica DB');
const groups = mongoose.connection.db.collection('groups'); const groups = mongoose.connection.db.collection('groups');
const users = mongoose.connection.db.collection('users'); const users = mongoose.connection.db.collection('users');
return mongoose.connection.dropDatabase() return mongoose.connection.dropDatabase()

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vite", "serve": "vite",
"serve:docker": "vite --host 0.0.0.0",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"test:unit": "vitest run", "test:unit": "vitest run",

View File

@@ -52,7 +52,7 @@
<div <div
v-if="!group.purchased.plan.dateTerminated v-if="!group.purchased.plan.dateTerminated
&& group.purchased.plan.paymentMethod === 'Stripe'" && group.purchased.plan.paymentMethod === 'Stripe'"
class="btn btn-primary mb-3" class="btn btn-primary"
@click="redirectToStripeEdit({groupId: group.id})" @click="redirectToStripeEdit({groupId: group.id})"
> >
{{ $t('subUpdateCard') }} {{ $t('subUpdateCard') }}

View File

@@ -189,7 +189,6 @@
> >
</p> </p>
<div <div
v-if="paymentMethodLogo.icon"
class="svg svg-icon mb-4" class="svg svg-icon mb-4"
:class="paymentMethodLogo.class" :class="paymentMethodLogo.class"
v-html="paymentMethodLogo.icon" v-html="paymentMethodLogo.icon"
@@ -206,13 +205,6 @@
<div>{{ $t('subUpdateCard') }}</div> <div>{{ $t('subUpdateCard') }}</div>
</button> </button>
</div> </div>
<div
v-once
v-if="!hasGroupPlan"
class="small text-center mb-4"
>
{{ $t('subscriptionBillingFYIShort') }}
</div>
<div <div
v-if="purchasedPlanExtraMonthsDetails.months > 0" v-if="purchasedPlanExtraMonthsDetails.months > 0"
class="extra-months green-10 py-2 px-3 mb-4" class="extra-months green-10 py-2 px-3 mb-4"
@@ -417,7 +409,6 @@
<div class="d-flex flex-column align-items-center mt-3"> <div class="d-flex flex-column align-items-center mt-3">
<div <div
v-once v-once
v-if="!hasSubscription"
class="small gray-100 w-50 text-center mb-5" class="small gray-100 w-50 text-center mb-5"
> >
{{ $t('subscriptionBillingFYI') }} {{ $t('subscriptionBillingFYI') }}

View File

@@ -273,6 +273,5 @@
"earn2GemsGift": "They'll earn <strong>+2 Gems</strong> every month they're subscribed", "earn2GemsGift": "They'll earn <strong>+2 Gems</strong> every month they're subscribed",
"maxGemCapGift": "They'll have the max <strong>Gem Cap</strong>", "maxGemCapGift": "They'll have the max <strong>Gem Cap</strong>",
"subscribeAgainContinueHourglasses": "Subscribe again to continue receiving Mystic Hourglasses", "subscribeAgainContinueHourglasses": "Subscribe again to continue receiving Mystic Hourglasses",
"subscriptionBillingFYI": "Subscriptions automatically renew unless you cancel at least 24 hours before the end of the current period. You can manage your subscription from the Subscription tab in settings. Your account will be charged within 24 hours of your renewal date, at the same price you initially paid.", "subscriptionBillingFYI": "Subscriptions automatically renew unless you cancel at least 24 hours before the end of the current period. You can manage your subscription from the Subscription tab in settings. Your account will be charged within 24 hours of your renewal date, at the same price you initially paid."
"subscriptionBillingFYIShort": "Subscriptions automatically renew unless you cancel at least 24 hours before the end of the current period. Your account will be charged within 24 hours of your renewal date, at the same price you initially paid."
} }

View File

@@ -109,8 +109,8 @@ export const REPEATING_EVENTS = {
foodSeason: 'Pie', foodSeason: 'Pie',
}, },
giftOneGetOne: { giftOneGetOne: {
start: new Date('1970-12-16T04:00-05:00'), start: new Date('1970-12-18T04:00-05:00'),
end: new Date('1970-01-09T23:59-05:00'), end: new Date('1970-01-05T23:59-05:00'),
promo: 'g1g1', promo: 'g1g1',
}, },
}; };