mirror of
https://github.com/sudoxnym/habitica-self-host.git
synced 2026-07-14 02:02:19 +00:00
Merge branch 'develop' into release
This commit is contained in:
commit
4db1b1cdfa
14 changed files with 866 additions and 1022 deletions
135
package-lock.json
generated
135
package-lock.json
generated
|
|
@ -1382,16 +1382,6 @@
|
|||
"@sinonjs/commons": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"@sinonjs/formatio": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz",
|
||||
"integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@sinonjs/commons": "^1",
|
||||
"@sinonjs/samsam": "^5.0.2"
|
||||
}
|
||||
},
|
||||
"@sinonjs/samsam": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.0.tgz",
|
||||
|
|
@ -1415,23 +1405,13 @@
|
|||
"integrity": "sha512-tA7GG7Tj479vojfV3AoxbckalA48aK6giGjNtgH6ihpLwTyHE3fIgRrvt8TWfLwW8X8dyu7vgmAsGLRG7hWWOg=="
|
||||
},
|
||||
"@slack/webhook": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@slack/webhook/-/webhook-5.0.3.tgz",
|
||||
"integrity": "sha512-51vnejJ2zABNumPVukOLyerpHQT39/Lt0TYFtOEz/N2X77bPofOgfPj2atB3etaM07mxWHLT9IRJ4Zuqx38DkQ==",
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@slack/webhook/-/webhook-5.0.4.tgz",
|
||||
"integrity": "sha512-IC1dpVSc2F/pmwCxOb0QzH2xnGKmyT7MofPGhNkeaoiMrLMU+Oc7xV/AxGnz40mURtCtaDchZSM3tDo9c9x6BA==",
|
||||
"requires": {
|
||||
"@slack/types": "^1.2.1",
|
||||
"@types/node": ">=8.9.0",
|
||||
"axios": "^0.19.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10"
|
||||
}
|
||||
}
|
||||
"axios": "^0.21.1"
|
||||
}
|
||||
},
|
||||
"@szmarczak/http-timer": {
|
||||
|
|
@ -1773,9 +1753,9 @@
|
|||
}
|
||||
},
|
||||
"apidoc": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/apidoc/-/apidoc-0.25.0.tgz",
|
||||
"integrity": "sha512-5g9fp8OffXZOdBTzm4BBvV5Vw54s+NmKnGZIUKuH+gRTqqJuRJpcGN6sz6WnjJ+NcvXhB7rIRp6FhtJahazx2Q==",
|
||||
"version": "0.26.0",
|
||||
"resolved": "https://registry.npmjs.org/apidoc/-/apidoc-0.26.0.tgz",
|
||||
"integrity": "sha512-IEw/Z7HMMbjeVjK2sZvZSwAln8AqalLzf3qLDtkcedXVhdxGm6W7UgIW6fshegqNTMLzm8CFEMi4Lxbeu0xKTw==",
|
||||
"requires": {
|
||||
"apidoc-core": "^0.12.0",
|
||||
"commander": "^2.20.0",
|
||||
|
|
@ -1795,15 +1775,10 @@
|
|||
"uc.micro": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-11.0.0.tgz",
|
||||
"integrity": "sha512-+CvOnmbSubmQFSA9dKz1BRiaSMV7rhexl3sngKqFyXSagoA3fBdJQ8oZWtRy2knXdpDXaBw44euz37DeJQ9asg==",
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-11.0.1.tgz",
|
||||
"integrity": "sha512-aU1TzmBKcWNNYvH9pjq6u92BML+Hz3h5S/QpfTFwiQF852pLT+9qHsrhM9JYipkOXZxGn+sGH8oyJE9FD9WezQ==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"entities": "~2.0.0",
|
||||
|
|
@ -1827,15 +1802,13 @@
|
|||
"semver": "~7.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
|
||||
"version": "7.3.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
|
||||
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1857,23 +1830,13 @@
|
|||
}
|
||||
},
|
||||
"apple-auth": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/apple-auth/-/apple-auth-1.0.6.tgz",
|
||||
"integrity": "sha512-dICsYIHBTX+7/1xdJZ4y4U08zOxEnL67GQ77l/HSKqEx9uC1wsY5dNjgbZf2F/1QnzAxDbAAHo0DgUCrA1k7zQ==",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/apple-auth/-/apple-auth-1.0.7.tgz",
|
||||
"integrity": "sha512-vfJqy4KtT5KHflxBSemc0mkWuy2GU2wHWaZ6xVWUjPmiXkJcLj5jB3IeCbDLF4wN+ZStjOQXZWfGwccBjclVlA==",
|
||||
"requires": {
|
||||
"axios": "^0.19.0",
|
||||
"axios": "^0.21.1",
|
||||
"express": "^4.17.1",
|
||||
"jsonwebtoken": "^8.5.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"aproba": {
|
||||
|
|
@ -8226,12 +8189,19 @@
|
|||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
|
||||
"integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^1.0.0"
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsonwebtoken": {
|
||||
|
|
@ -8310,9 +8280,9 @@
|
|||
}
|
||||
},
|
||||
"jwks-rsa": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-1.12.1.tgz",
|
||||
"integrity": "sha512-N7RsfrzK3+S+SqKEEhWF7Ak87Gzg0KcZq/f8h0VqL2ur3nTB6pi5J12uelGAzB3VfhWQI+zfolHE2XDu/EI7Hg==",
|
||||
"version": "1.12.2",
|
||||
"resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-1.12.2.tgz",
|
||||
"integrity": "sha512-6gPo/mQUxXJt75oPtjhM3Jm3FSXnmwg73QDA8dpgP7YmIKlIY+2StngFxt4w4Y1podtSbtV3jttNOdctuxAX1Q==",
|
||||
"requires": {
|
||||
"@types/express-jwt": "0.0.42",
|
||||
"axios": "^0.21.1",
|
||||
|
|
@ -9361,9 +9331,9 @@
|
|||
}
|
||||
},
|
||||
"mongoose": {
|
||||
"version": "5.11.10",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.11.10.tgz",
|
||||
"integrity": "sha512-daE2L6VW7WNywv7tL2KUkBViWvODbzr50Of1kJpIbzW3w3N5/TYcgSmhCsEDWfYGQXbun2rdd7+sOdsEC8zQSQ==",
|
||||
"version": "5.11.11",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.11.11.tgz",
|
||||
"integrity": "sha512-JgKKAosJf6medPOZi2LmO7sMz7Sg00mgjyPAKari3alzL+R/n8D+zKK29iGtJpNNtv9IKy14H37CWuiaZ7016w==",
|
||||
"requires": {
|
||||
"@types/mongodb": "^3.5.27",
|
||||
"bson": "^1.1.4",
|
||||
|
|
@ -9628,9 +9598,9 @@
|
|||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
|
||||
},
|
||||
"nconf": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/nconf/-/nconf-0.11.0.tgz",
|
||||
"integrity": "sha512-c4W7QqYF6p5BC7J/eVTOvtUlQgvS5CgbJ11xgjhSr8yyius7km7xgdIYHkFLR4TWY1HjsFkia/3l5OprGqCHvA==",
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/nconf/-/nconf-0.11.1.tgz",
|
||||
"integrity": "sha512-2XY+7x3GwkkTnmkEVxsKykg0GUqCAtBZUA87FwbcUSaYBfaGCeVSf+82zap16j93B21J2AhpxrsF57jio36t0w==",
|
||||
"requires": {
|
||||
"async": "^1.4.0",
|
||||
"ini": "^1.3.0",
|
||||
|
|
@ -9708,9 +9678,9 @@
|
|||
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.1.tgz",
|
||||
"integrity": "sha512-hAD1RcFP/wfgfxgMVswPE+z3tlPFtxG8/yWUrG2i17sTWGCGqWnxKcLTF4cUKDUK8fzokwsmO9H0TDkRbMHy8w==",
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"requires": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
|
|
@ -11163,9 +11133,9 @@
|
|||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||
},
|
||||
"rate-limiter-flexible": {
|
||||
"version": "2.1.16",
|
||||
"resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-2.1.16.tgz",
|
||||
"integrity": "sha512-ag2ZQLS0g7+QrMpmMQf37EJ/9drSOsrslQXnOJ3OpqIgUwdjQpChu8CLNz4GWOr9sJq+RGVYDwAcJjYK8hHCqA=="
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-2.2.1.tgz",
|
||||
"integrity": "sha512-rxCP6kDDdn0cZmVqVlF06yLU+mG3TuwaHV/fUIw3OQyYhza7pzVBtdMhUmfXbBzMS+O464XP+x33pfTDGRGYVA=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.4.0",
|
||||
|
|
@ -12031,14 +12001,13 @@
|
|||
}
|
||||
},
|
||||
"sinon": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.2.tgz",
|
||||
"integrity": "sha512-9Owi+RisvCZpB0bdOVFfL314I6I4YoRlz6Isi4+fr8q8YQsDPoCe5UnmNtKHRThX3negz2bXHWIuiPa42vM8EQ==",
|
||||
"version": "9.2.3",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.3.tgz",
|
||||
"integrity": "sha512-m+DyAWvqVHZtjnjX/nuShasykFeiZ+nPuEfD4G3gpvKGkXRhkF/6NSt2qN2FjZhfrcHXFzUzI+NLnk+42fnLEw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@sinonjs/commons": "^1.8.1",
|
||||
"@sinonjs/fake-timers": "^6.0.1",
|
||||
"@sinonjs/formatio": "^5.0.1",
|
||||
"@sinonjs/samsam": "^5.3.0",
|
||||
"diff": "^4.0.2",
|
||||
"nise": "^4.0.4",
|
||||
|
|
@ -12724,9 +12693,9 @@
|
|||
}
|
||||
},
|
||||
"stripe": {
|
||||
"version": "8.129.0",
|
||||
"resolved": "https://registry.npmjs.org/stripe/-/stripe-8.129.0.tgz",
|
||||
"integrity": "sha512-73b49GQg2+ig6Cet11QhN1WgBab+2xtHy57W4ZLRd9dq146vz+vik+kMQ7UAcTSF5vYyTM5Zo6POMZDPXqzWUg==",
|
||||
"version": "8.130.0",
|
||||
"resolved": "https://registry.npmjs.org/stripe/-/stripe-8.130.0.tgz",
|
||||
"integrity": "sha512-9e283EFhxDz7SUcgNiUFRdTZ/kS2IkoT0KBMOJHdf3vY+mvURq355s2E0Zyy9rtNmt+CEZ0nCMiZ3PqIqpp6Pg==",
|
||||
"requires": {
|
||||
"@types/node": ">=8.1.0",
|
||||
"qs": "^6.6.0"
|
||||
|
|
|
|||
18
package.json
18
package.json
|
|
@ -9,12 +9,12 @@
|
|||
"@babel/register": "^7.12.10",
|
||||
"@google-cloud/trace-agent": "^5.1.1",
|
||||
"@parse/node-apn": "^4.0.0",
|
||||
"@slack/webhook": "^5.0.3",
|
||||
"@slack/webhook": "^5.0.4",
|
||||
"accepts": "^1.3.5",
|
||||
"amazon-payments": "^0.2.8",
|
||||
"amplitude": "^5.1.4",
|
||||
"apidoc": "^0.25.0",
|
||||
"apple-auth": "^1.0.6",
|
||||
"apidoc": "^0.26.0",
|
||||
"apple-auth": "^1.0.7",
|
||||
"bcrypt": "^5.0.0",
|
||||
"body-parser": "^1.18.3",
|
||||
"compression": "^1.7.4",
|
||||
|
|
@ -42,15 +42,15 @@
|
|||
"in-app-purchase": "^1.11.3",
|
||||
"js2xmlparser": "^4.0.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jwks-rsa": "^1.12.1",
|
||||
"jwks-rsa": "^1.12.2",
|
||||
"lodash": "^4.17.20",
|
||||
"merge-stream": "^2.0.0",
|
||||
"method-override": "^3.0.0",
|
||||
"moment": "^2.29.1",
|
||||
"moment-recur": "^1.0.7",
|
||||
"mongoose": "^5.11.10",
|
||||
"mongoose": "^5.11.11",
|
||||
"morgan": "^1.10.0",
|
||||
"nconf": "^0.11.0",
|
||||
"nconf": "^0.11.1",
|
||||
"node-gcm": "^1.0.3",
|
||||
"on-headers": "^1.0.2",
|
||||
"passport": "^0.4.1",
|
||||
|
|
@ -60,13 +60,13 @@
|
|||
"paypal-rest-sdk": "^1.8.1",
|
||||
"pp-ipn": "^1.1.0",
|
||||
"ps-tree": "^1.0.0",
|
||||
"rate-limiter-flexible": "^2.1.16",
|
||||
"rate-limiter-flexible": "^2.2.1",
|
||||
"redis": "^3.0.2",
|
||||
"regenerator-runtime": "^0.13.7",
|
||||
"remove-markdown": "^0.3.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"short-uuid": "^4.1.0",
|
||||
"stripe": "^8.129.0",
|
||||
"stripe": "^8.130.0",
|
||||
"superagent": "^6.1.0",
|
||||
"universal-analytics": "^0.4.23",
|
||||
"useragent": "^2.1.9",
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
"monk": "^7.3.2",
|
||||
"require-again": "^2.0.0",
|
||||
"run-rs": "^0.7.3",
|
||||
"sinon": "^9.2.2",
|
||||
"sinon": "^9.2.3",
|
||||
"sinon-chai": "^3.5.0",
|
||||
"sinon-stub-promise": "^4.0.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,9 +8,14 @@ import {
|
|||
|
||||
describe('POST /tasks/user', () => {
|
||||
let user;
|
||||
let tzoffset;
|
||||
|
||||
before(async () => {
|
||||
tzoffset = new Date().getTimezoneOffset();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
user = await generateUser();
|
||||
user = await generateUser({ 'preferences.timezoneOffset': tzoffset });
|
||||
});
|
||||
|
||||
context('validates params', async () => {
|
||||
|
|
@ -544,7 +549,7 @@ describe('POST /tasks/user', () => {
|
|||
expect(task.everyX).to.eql(5);
|
||||
expect(task.daysOfMonth).to.eql([15]);
|
||||
expect(task.weeksOfMonth).to.eql([3]);
|
||||
expect(new Date(task.startDate)).to.eql(now);
|
||||
expect(new Date(task.startDate)).to.eql(new Date(now.setHours(0, 0, 0, 0)));
|
||||
expect(task.isDue).to.be.true;
|
||||
expect(task.nextDue.length).to.eql(6);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,9 +10,14 @@ import {
|
|||
|
||||
describe('PUT /tasks/:id', () => {
|
||||
let user;
|
||||
let tzoffset;
|
||||
|
||||
before(async () => {
|
||||
tzoffset = (new Date()).getTimezoneOffset();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
user = await generateUser();
|
||||
user = await generateUser({ 'preferences.timezoneOffset': tzoffset });
|
||||
});
|
||||
|
||||
context('validates params', () => {
|
||||
|
|
@ -503,7 +508,8 @@ describe('PUT /tasks/:id', () => {
|
|||
let monthly;
|
||||
|
||||
beforeEach(async () => {
|
||||
const date1 = moment.utc('2020-07-01').toDate();
|
||||
// using date literals is discouraged here, daylight savings will break everything
|
||||
const date1 = moment().toDate();
|
||||
monthly = await user.post('/tasks/user', {
|
||||
text: 'test monthly',
|
||||
type: 'daily',
|
||||
|
|
@ -514,7 +520,7 @@ describe('PUT /tasks/:id', () => {
|
|||
});
|
||||
|
||||
it('updates days of month when start date updated', async () => {
|
||||
const date2 = moment.utc('2020-07-01').toDate();
|
||||
const date2 = moment().add(6, 'months').toDate();
|
||||
const savedMonthly = await user.put(`/tasks/${monthly._id}`, {
|
||||
startDate: date2,
|
||||
});
|
||||
|
|
@ -523,18 +529,30 @@ describe('PUT /tasks/:id', () => {
|
|||
});
|
||||
|
||||
it('updates next due when start date updated', async () => {
|
||||
const date2 = moment.utc('2022-07-01').toDate();
|
||||
const date2 = moment().add(6, 'months').toDate();
|
||||
const savedMonthly = await user.put(`/tasks/${monthly._id}`, {
|
||||
startDate: date2,
|
||||
});
|
||||
|
||||
expect(savedMonthly.nextDue.length).to.eql(6);
|
||||
expect(moment(savedMonthly.nextDue[0]).toDate()).to.eql(moment.utc('2022-08-01').toDate());
|
||||
expect(moment(savedMonthly.nextDue[1]).toDate()).to.eql(moment.utc('2022-09-01').toDate());
|
||||
expect(moment(savedMonthly.nextDue[2]).toDate()).to.eql(moment.utc('2022-10-01').toDate());
|
||||
expect(moment(savedMonthly.nextDue[3]).toDate()).to.eql(moment.utc('2022-11-01').toDate());
|
||||
expect(moment(savedMonthly.nextDue[4]).toDate()).to.eql(moment.utc('2022-12-01').toDate());
|
||||
expect(moment(savedMonthly.nextDue[5]).toDate()).to.eql(moment.utc('2023-01-01').toDate());
|
||||
expect(moment(savedMonthly.nextDue[0]).toDate()).to.eql(
|
||||
moment(date2).add(1, 'months').startOf('day').toDate(),
|
||||
);
|
||||
expect(moment(savedMonthly.nextDue[1]).toDate()).to.eql(
|
||||
moment(date2).add(2, 'months').startOf('day').toDate(),
|
||||
);
|
||||
expect(moment(savedMonthly.nextDue[2]).toDate()).to.eql(
|
||||
moment(date2).add(3, 'months').startOf('day').toDate(),
|
||||
);
|
||||
expect(moment(savedMonthly.nextDue[3]).toDate()).to.eql(
|
||||
moment(date2).add(4, 'months').startOf('day').toDate(),
|
||||
);
|
||||
expect(moment(savedMonthly.nextDue[4]).toDate()).to.eql(
|
||||
moment(date2).add(5, 'months').startOf('day').toDate(),
|
||||
);
|
||||
expect(moment(savedMonthly.nextDue[5]).toDate()).to.eql(
|
||||
moment(date2).add(6, 'months').startOf('day').toDate(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -11,13 +11,18 @@ describe('POST /tasks/challenge/:challengeId', () => {
|
|||
let user;
|
||||
let guild;
|
||||
let challenge;
|
||||
let tzoffset;
|
||||
|
||||
function findUserChallengeTask (memberTask) {
|
||||
return memberTask.challenge.id === challenge._id;
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
tzoffset = new Date().getTimezoneOffset();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
user = await generateUser({ balance: 1 });
|
||||
user = await generateUser({ balance: 1, 'preferences.timezoneOffset': tzoffset });
|
||||
guild = await generateGroup(user);
|
||||
challenge = await generateChallenge(user, guild);
|
||||
await user.post(`/challenges/${challenge._id}/join`);
|
||||
|
|
@ -165,7 +170,7 @@ describe('POST /tasks/challenge/:challengeId', () => {
|
|||
expect(task.type).to.eql('daily');
|
||||
expect(task.frequency).to.eql('daily');
|
||||
expect(task.everyX).to.eql(5);
|
||||
expect(new Date(task.startDate)).to.eql(now);
|
||||
expect(new Date(task.startDate)).to.eql(new Date(now.setHours(0, 0, 0, 0)));
|
||||
|
||||
expect(userChallengeTask.notes).to.eql(task.notes);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ describe('PUT /tasks/:id', () => {
|
|||
let challenge;
|
||||
|
||||
before(async () => {
|
||||
user = await generateUser();
|
||||
user = await generateUser({ 'preferences.timezoneOffset': new Date().getTimezoneOffset() });
|
||||
guild = await generateGroup(user);
|
||||
challenge = await generateChallenge(user, guild);
|
||||
await user.post(`/challenges/${challenge._id}/join`);
|
||||
|
|
|
|||
|
|
@ -8,12 +8,18 @@ import {
|
|||
describe('POST /tasks/group/:groupid', () => {
|
||||
let user; let guild; let
|
||||
manager;
|
||||
let tzoffset;
|
||||
const groupName = 'Test Public Guild';
|
||||
const groupType = 'guild';
|
||||
|
||||
before(async () => {
|
||||
tzoffset = new Date().getTimezoneOffset();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
user = await generateUser({ balance: 1 });
|
||||
// user = await generateUser({ balance: 1, 'preferences.timezoneOffset': tzoffset });
|
||||
const { group, groupLeader, members } = await createAndPopulateGroup({
|
||||
leaderDetails: { balance: 10, 'preferences.timezoneOffset': tzoffset },
|
||||
groupDetails: {
|
||||
name: groupName,
|
||||
type: groupType,
|
||||
|
|
@ -128,7 +134,7 @@ describe('POST /tasks/group/:groupid', () => {
|
|||
expect(task.type).to.eql('daily');
|
||||
expect(task.frequency).to.eql('daily');
|
||||
expect(task.everyX).to.eql(5);
|
||||
expect(new Date(task.startDate)).to.eql(now);
|
||||
expect(new Date(task.startDate)).to.eql(new Date(now.setHours(0, 0, 0, 0)));
|
||||
});
|
||||
|
||||
it('allows a manager to add a group task', async () => {
|
||||
|
|
|
|||
1603
website/client/package-lock.json
generated
1603
website/client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -18,13 +18,13 @@
|
|||
"@storybook/addon-links": "^5.3.19",
|
||||
"@storybook/addon-notes": "^5.3.21",
|
||||
"@storybook/vue": "^5.3.19",
|
||||
"@vue/cli-plugin-babel": "^4.5.9",
|
||||
"@vue/cli-plugin-eslint": "^4.5.9",
|
||||
"@vue/cli-plugin-router": "^4.5.9",
|
||||
"@vue/cli-plugin-unit-mocha": "^4.5.9",
|
||||
"@vue/cli-service": "^4.5.9",
|
||||
"@vue/cli-plugin-babel": "^4.5.10",
|
||||
"@vue/cli-plugin-eslint": "^4.5.10",
|
||||
"@vue/cli-plugin-router": "^4.5.10",
|
||||
"@vue/cli-plugin-unit-mocha": "^4.5.10",
|
||||
"@vue/cli-service": "^4.5.10",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"amplitude-js": "^7.3.3",
|
||||
"amplitude-js": "^7.4.0",
|
||||
"axios": "^0.21.1",
|
||||
"axios-progress-bar": "^1.2.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
|
|
@ -43,8 +43,8 @@
|
|||
"jquery": "^3.5.1",
|
||||
"lodash": "^4.17.20",
|
||||
"moment": "^2.29.1",
|
||||
"nconf": "^0.11.0",
|
||||
"sass": "^1.32.0",
|
||||
"nconf": "^0.11.1",
|
||||
"sass": "^1.32.2",
|
||||
"sass-loader": "^8.0.2",
|
||||
"smartbanner.js": "^1.16.0",
|
||||
"svg-inline-loader": "^0.8.2",
|
||||
|
|
@ -60,6 +60,6 @@
|
|||
"vue-template-compiler": "^2.6.12",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#153d339e4dbebb73733658aeda1d5b7fcc55b0a0",
|
||||
"webpack": "^4.44.2"
|
||||
"webpack": "^4.45.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@
|
|||
"PMUnblockUserToSendMessages": "Unblock this user to continue sending and receiving messages.",
|
||||
"block": "Block",
|
||||
"unblock": "Un-block",
|
||||
"blockYourself": "You cannot block yourself",
|
||||
"blockWarning": "Block - This will have no effect if the player is a moderator now or becomes a moderator in future.",
|
||||
"inbox": "Inbox",
|
||||
"messageRequired": "A message is required.",
|
||||
|
|
|
|||
|
|
@ -2916,6 +2916,7 @@ const weapon = {
|
|||
notes: t('weaponSpecialSummer2019MageNotes', { int: 15 }),
|
||||
value: 90,
|
||||
int: 15,
|
||||
per: 0,
|
||||
twoHanded: false,
|
||||
canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -678,18 +678,29 @@ api.updateTask = {
|
|||
task.group.managerNotes = sanitizedObj.managerNotes;
|
||||
}
|
||||
|
||||
// If the daily task was set to repeat monthly on a day of the month, and the start date was
|
||||
// updated, the task will then need to be updated to repeat on the same day of the month as the
|
||||
// new start date. For example, if the start date is updated to 7/2/2020, the daily should
|
||||
// repeat on the 2nd day of the month. It's possible that a task can repeat monthly on a
|
||||
// week of the month, in which case we won't update the repetition at all.
|
||||
if (
|
||||
task.type === 'daily'
|
||||
&& task.frequency === 'monthly'
|
||||
&& task.daysOfMonth.length
|
||||
&& task.startDate
|
||||
// For daily tasks, update start date based on timezone to maintain consistency
|
||||
if (task.type === 'daily'
|
||||
&& task.startDate
|
||||
) {
|
||||
task.daysOfMonth = [moment(task.startDate).date()];
|
||||
task.startDate = moment(task.startDate).utcOffset(
|
||||
-user.preferences.timezoneOffset,
|
||||
).startOf('day').toDate();
|
||||
|
||||
// If the daily task was set to repeat monthly on a day of the month, and the start date was
|
||||
// updated, the task will then need to be updated to repeat on the same day of the month as
|
||||
// the new start date. For example, if the start date is updated to 7/2/2020, the daily
|
||||
// should repeat on the 2nd day of the month. It's possible that a task can repeat monthly
|
||||
// on a week of the month, in which case we won't update the repetition at all.
|
||||
if (
|
||||
task.frequency === 'monthly'
|
||||
&& task.daysOfMonth.length
|
||||
) {
|
||||
// We also need to aware of the user's timezone. Start date is represented as UTC, so the
|
||||
// start date and day of month might be different
|
||||
task.daysOfMonth = [moment(task.startDate).utcOffset(
|
||||
-user.preferences.timezoneOffset,
|
||||
).date()];
|
||||
}
|
||||
}
|
||||
|
||||
setNextDue(task, user);
|
||||
|
|
|
|||
|
|
@ -124,6 +124,15 @@ export async function createTasks (req, res, options = {}) {
|
|||
}
|
||||
}
|
||||
|
||||
// set startDate to midnight in the user's timezone
|
||||
if (taskType === 'daily') {
|
||||
const awareStartDate = moment(newTask.startDate).utcOffset(-user.preferences.timezoneOffset);
|
||||
if (awareStartDate.format('HMsS') !== '0000') {
|
||||
awareStartDate.startOf('day');
|
||||
newTask.startDate = awareStartDate.toDate();
|
||||
}
|
||||
}
|
||||
|
||||
setNextDue(newTask, user);
|
||||
|
||||
// Validate that the task is valid and throw if it isn't
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ export const DailySchema = new Schema(_.defaults({
|
|||
startDate: {
|
||||
$type: Date,
|
||||
default () {
|
||||
return moment().startOf('day').toDate();
|
||||
return moment.utc().toDate();
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue