allow admins to manipulate time on test servers

This commit is contained in:
Phillip Thelen
2024-02-15 13:09:46 +01:00
committed by Sabe Jones
parent 1b12e9d8b7
commit 593524905e
6 changed files with 109 additions and 37 deletions

View File

@@ -87,5 +87,6 @@
"REDIS_HOST": "aaabbbcccdddeeefff",
"REDIS_PORT": "1234",
"REDIS_PASSWORD": "12345678",
"TRUSTED_DOMAINS": "localhost,https://habitica.com"
"TRUSTED_DOMAINS": "localhost,https://habitica.com",
"ENABLE_TIME_TRAVEL": "false"
}

View File

@@ -290,6 +290,31 @@
>{{ $t('terms') }}</a>
</div>
<div
v-if="ENABLE_TIME_TRAVEL && user.permissions.fullAccess">
<a
class="btn btn-secondary mr-1"
@click="jumpTime(-1)">-1 Day</a>
<a
class="btn btn-secondary mr-1"
@click="jumpTime(-7)">-7 Days</a>
<a
class="btn btn-secondary mr-1"
@click="jumpTime(-30)">-30 Days</a>
<div class="my-2">
Time Traveling! It is {{ new Date().toLocaleString() }}
</div>
<a
class="btn btn-secondary mr-1"
@click="jumpTime(1)">+1 Day</a>
<a
class="btn btn-secondary mr-1"
@click="jumpTime(7)">+7 Days</a>
<a
class="btn btn-secondary mr-1"
@click="jumpTime(30)">+30 Days</a>
</div>
<div
v-if="!IS_PRODUCTION && isUserLoaded"
class="debug-toggle"
@@ -300,9 +325,6 @@
>
Toggle Debug Menu
</button>
<div>
Today is {{ new Date() }}
</div>
<div
v-if="debugMenuShown"
class="debug-toggle debug-group"
@@ -775,6 +797,7 @@ h3 {
// modules
import axios from 'axios';
import moment from 'moment';
import Vue from 'vue';
// images
import melior from '@/assets/svg/melior.svg';
@@ -790,6 +813,7 @@ import buyGemsModal from './payments/buyGemsModal.vue';
import reportBug from '@/mixins/reportBug.js';
const IS_PRODUCTION = process.env.NODE_ENV === 'production'; // eslint-disable-line no-process-env
const ENABLE_TIME_TRAVEL = process.env.ENABLE_TIME_TRAVEL === 'true'; // eslint-disable-line no-process-env
export default {
components: {
buyGemsModal,
@@ -807,6 +831,7 @@ export default {
}),
debugMenuShown: false,
IS_PRODUCTION,
ENABLE_TIME_TRAVEL,
};
},
computed: {
@@ -868,6 +893,15 @@ export default {
'stats.mp': this.user.stats.mp + 10000,
});
},
async jumpTime (amount) {
const response = await axios.post('/api/v4/debug/jump-time', { offsetDays: amount });
console.log(response.data.data);
if (amount > 0) {
Vue.config.clock.jump(amount * 24 * 60 * 60 * 1000);
} else {
Vue.config.clock.setSystemTime(moment().add(amount, 'days').toDate());
}
},
addExp () {
// @TODO: Name these variables better
let exp = 0;

View File

@@ -1,5 +1,4 @@
import Vue from 'vue';
import sinon from 'sinon';
import BootstrapVue from 'bootstrap-vue';
import Fragment from 'vue-fragment';
import AppComponent from './app';
@@ -14,7 +13,6 @@ import './filters/registerGlobals';
import i18n from './libs/i18n';
import 'smartbanner.js/dist/smartbanner';
let jumped = false;
const IS_PRODUCTION = process.env.NODE_ENV === 'production'; // eslint-disable-line no-process-env
// Configure Vue global options, see https://vuejs.org/v2/api/#Global-Config
@@ -37,20 +35,21 @@ setUpLogging();
setupAnalytics(); // just create queues for analytics, no scripts loaded at this time
const store = getStore();
const time = new Date(2024, 2, 18);
const clock = sinon.useFakeTimers({
now: time,
shouldAdvanceTime: true,
});
if (process.env.ENABLE_TIME_TRAVEL) {
(async () => {
const sinon = await import('sinon');
const axios = await import('axios');
const response = await axios.get('/api/v4/debug/time-travel-time');
console.log(response.data.data.time);
const time = new Date(response.data.data.time);
Vue.config.clock = sinon.useFakeTimers({
now: time,
shouldAdvanceTime: true,
});
setInterval(() => {
if (jumped) {
jumped = false;
return;
}
jumped = true;
clock.jump(36000);
}, 1000);
console.log('Time travel mode activated. It is now', new Date());
})();
}
const vueInstance = new Vue({
el: '#app',

View File

@@ -28,6 +28,7 @@ const envVars = [
'AMPLITUDE_KEY',
'LOGGLY_CLIENT_TOKEN',
'TRUSTED_DOMAINS',
'ENABLE_TIME_TRAVEL',
// TODO necessary? if yes how not to mess up with vue cli? 'NODE_ENV'
];

View File

@@ -1,4 +1,6 @@
import _ from 'lodash';
import nconf from 'nconf';
import moment from 'moment';
import { authWithHeaders } from '../../middlewares/auth';
import ensureDevelpmentMode from '../../middlewares/ensureDevelpmentMode';
import { BadRequest } from '../../libs/errors';
@@ -201,4 +203,57 @@ api.questProgress = {
},
};
let clock;
if (nconf.get('ENABLE_TIME_TRAVEL')) {
(async () => {
const sinon = await import('sinon');
const time = new Date();
clock = sinon.useFakeTimers({
now: time,
shouldAdvanceTime: true,
});
})();
api.timeTravelTime = {
method: 'GET',
url: '/debug/time-travel-time',
middlewares: [authWithHeaders()],
async handler (req, res) {
const { user } = res.locals;
if (!user.permissions.fullAccess) {
throw new BadRequest('You do not have permission to time travel.');
}
res.respond(200, {
time: new Date(),
});
},
}
api.timeTravelAdjust = {
method: 'POST',
url: '/debug/jump-time',
middlewares: [authWithHeaders()],
async handler (req, res) {
const { user } = res.locals;
if (!user.permissions.fullAccess) {
throw new BadRequest('You do not have permission to time travel.');
}
const { offsetDays } = req.body;
if (offsetDays > 0) {
clock.jump(offsetDays * 24 * 60 * 60 * 1000)
} else {
clock.setSystemTime(moment().add(offsetDays, 'days').toDate());
}
res.respond(200, {
time: new Date(),
});
},
}
}
export default api;

View File

@@ -2,7 +2,6 @@ import nconf from 'nconf';
import express from 'express';
import http from 'http';
import logger from './libs/logger';
import sinon from 'sinon';
// Setup translations
// Must come before attach middlewares so Mongoose validations can use translations
@@ -26,23 +25,6 @@ app.set('port', nconf.get('PORT'));
attachMiddlewares(app, server);
const time = new Date(2024, 2, 18);
const clock = sinon.useFakeTimers({
now: time,
shouldAdvanceTime: true,
});
var jumped = false;
setInterval(() => {
if (jumped) {
jumped = false;
return;
}
jumped = true;
console.log('Jumping time');
clock.jump(36000);
}, 1000);
server.on('request', app);
server.listen(app.get('port'), () => {
logger.info(`Express server listening on port ${app.get('port')}`);