Compare commits

...

26 Commits

Author SHA1 Message Date
Hafiz 95dfb37512 Fix shop tabs overflow off screen at certain zoom levels
Fix quest cards get cut off on small screens
Fix pop-up windows extend past screen edges on mobile
2025-08-12 10:18:51 -05:00
Hafiz 9a1fb18959 Merge remote-tracking branch 'origin/develop' into qa/bat 2025-08-12 09:46:07 -05:00
Phillip Thelen 2ea0b64603 improve blocker form display 2025-08-05 14:57:25 +02:00
Phillip Thelen bd1aa1e417 validate blocker value during input 2025-08-05 14:45:23 +02:00
Phillip Thelen 7c49b845d6 add option to errorHandler to skip logging 2025-08-04 17:40:26 +02:00
Phillip Thelen 1ee172139d lint fix 2025-08-04 16:32:40 +02:00
Phillip Thelen 6447b9ab4b update block error strings 2025-08-04 16:03:55 +02:00
Phillip Thelen 5c414099d9 improve navbar display for non fullAccess admin 2025-08-04 14:46:05 +02:00
Phillip Thelen 5e8e1179aa fix managing permissions from admin 2025-08-04 14:45:47 +02:00
Phillip Thelen 7e86a62624 improve permission check 2025-08-04 14:33:09 +02:00
Phillip Thelen 1ba9dda0ed add new permission for managing blockers 2025-08-04 14:21:36 +02:00
Phillip Thelen 227e5ceaa8 fix import 2025-07-30 11:26:55 +02:00
Phillip Thelen f77ab5a3ab lint fixes 2025-07-30 11:26:55 +02:00
Phillip Thelen 1916faf647 fix 2025-07-30 11:26:55 +02:00
Phillip Thelen 80ecb5cef1 lint fix 2025-07-30 11:26:55 +02:00
Phillip Thelen 75c36e6622 add blocker to block emails from registration 2025-07-30 11:26:55 +02:00
Phillip Thelen 78330c975a Improve blocker UI 2025-07-30 11:26:55 +02:00
Phillip Thelen 95266f6cb3 improve test coverage 2025-07-30 11:26:55 +02:00
Phillip Thelen e9b2c1b51a restructure admin pages 2025-07-30 11:26:54 +02:00
Phillip Thelen 2a2bea07ab Add UI for managing blockers 2025-07-30 11:26:54 +02:00
Phillip Thelen ea60ddbf4c Tweak wording 2025-07-30 11:25:51 +02:00
Phillip Thelen 1c2ca0e478 correctly reset local data after creating blocker 2025-07-30 11:25:51 +02:00
Phillip Thelen ef2b7eb928 Add UI for managing blockers 2025-07-30 11:25:51 +02:00
Phillip Thelen 3d16387a61 add new frontend files 2025-07-30 11:25:41 +02:00
Phillip Thelen 93b7770eaa begin building general blocking solution 2025-07-30 11:25:41 +02:00
Phillip Thelen a9f84d3307 Read IP blocks from database 2025-07-30 11:25:41 +02:00
11 changed files with 141 additions and 13 deletions
+10 -1
View File
@@ -117,6 +117,15 @@ describe('Blocker middleware', () => {
checkIPBlockedErrorThrown(next);
});
it('throws when the ip is blocked', () => {
req.ip = '192.168.1.1';
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.1');
const attachBlocker = requireAgain(pathToBlocker).default;
attachBlocker(req, res, next);
checkIPBlockedErrorThrown(next);
});
});
describe('Blocking clients', () => {
@@ -194,4 +203,4 @@ describe('Blocker middleware', () => {
expect(calledWith[0] instanceof Forbidden).to.equal(true);
});
});
});
});
@@ -130,4 +130,4 @@ export default {
},
},
};
</script>
</script>
@@ -218,13 +218,19 @@
flex-direction: row;
flex-wrap: wrap;
gap: 0.5rem;
// somehow the browser felt like setting this 398px instead
// now its fixed to 400 :)
width: 400px;
max-width: 400px;
width: 100%;
margin-bottom: 1.5rem;
@media (max-width: 589px) {
max-width: 100%;
justify-content: center;
}
@media (max-width: 353px) {
gap: 0.25rem;
}
.quest-col {
::v-deep {
.item-wrapper {
@@ -251,6 +257,28 @@
::v-deep & {
.modal-dialog {
width: 448px !important;
max-width: calc(100vw - 20px);
margin: 0.5rem auto;
display: flex;
@media (max-width: 468px) {
width: 100% !important;
}
@media (max-width: 353px) {
width: 100% !important;
margin: 0.25rem auto;
}
}
.modal-content {
display: flex;
flex-direction: column;
width: 100%;
@media (max-width: 300px) {
border-radius: 0;
}
}
}
@@ -12,6 +12,12 @@
box-shadow: 0 1px 2px 0 rgba($black, 0.2);
z-index: 9;
height: 3rem;
flex-wrap: wrap;
@media (max-width: 683px) {
height: auto;
min-height: 3rem;
}
}
.nav-link {
@@ -23,6 +29,19 @@
padding: 0.75rem;
color: $gray-50;
white-space: nowrap;
@media (max-width: 683px) {
padding: 0.5rem;
font-size: 13px;
flex: 1 1 auto;
min-width: fit-content;
}
@media (max-width: 576px) {
padding: 0.5rem 0.4rem;
font-size: 12px;
}
&.active {
color: $purple-300;
@@ -269,7 +269,13 @@
.modal-dialog {
width: 448px;
max-width: calc(100vw - 20px);
box-sizing: border-box;
display: flex;
@media (max-width: 468px) {
width: 100%;
}
}
.badge-dialog {
@@ -346,7 +352,23 @@
.content {
text-align: center;
width: 448px;
width: 100%;
max-width: 448px;
margin: 0 auto;
@media (max-width: 468px) {
max-width: 100%;
}
}
.modal-content {
display: flex;
flex-direction: column;
width: 100%;
@media (max-width: 300px) {
border-radius: 0;
}
}
.item-wrapper {
@@ -111,6 +111,22 @@
.modal-dialog {
width: 448px;
max-width: calc(100vw - 20px);
display: flex;
@media (max-width: 468px) {
width: 100%;
}
}
.modal-content {
display: flex;
flex-direction: column;
width: 100%;
@media (max-width: 300px) {
border-radius: 0;
}
}
.modal-body {
@@ -165,6 +165,28 @@
.modal-dialog {
margin-top: 8%;
width: 448px !important;
max-width: calc(100vw - 20px);
display: flex;
@media (max-width: 468px) {
width: 100% !important;
margin: 0.5rem auto;
margin-top: 2%;
}
@media (max-width: 353px) {
margin: 0.25rem auto;
}
}
.modal-content {
display: flex;
flex-direction: column;
width: 100%;
@media (max-width: 300px) {
border-radius: 0;
}
}
.content {
+1 -1
View File
@@ -4,4 +4,4 @@
"newsroom": "Newsroom",
"adminBlockerTypeDescription": "<b>IP-Address</b> - Block access for a specific IP-Address\n\nClient - Block access for a client based on the \"x-client\" header.\n\nE-Mail - Blocks e-mails from being used for signup.",
"adminBlockerAreaDescription": "A blocker can either apply to the full site, completely blocking any access. Or it can apply to purchases, which still allows the site to be accessed."
}
}
@@ -187,5 +187,4 @@ api.deleteBlocker = {
res.respond(200, savedBlocker);
},
};
export default api;
+15 -2
View File
@@ -1,3 +1,4 @@
import nconf from 'nconf';
import {
Forbidden,
} from '../libs/errors';
@@ -9,7 +10,19 @@ import { model as Blocker } from '../models/blocker';
// NOTE: it's meant to be used behind a proxy (for example a load balancer)
// that uses the 'x-forwarded-for' header to forward the original IP addresses.
const blockedIps = [];
// A list of comma separated IPs to block
// It works fine as long as the list is short,
// if the list becomes too long for an env variable we'll switch to Redis.
const BLOCKED_IPS_RAW = nconf.get('BLOCKED_IPS');
const blockedIps = BLOCKED_IPS_RAW
? BLOCKED_IPS_RAW
.trim()
.split(',')
.map(blockedIp => blockedIp.trim())
.filter(blockedIp => Boolean(blockedIp))
: [];
const blockedClients = [];
Blocker.watchBlockers({
@@ -53,4 +66,4 @@ export default function ipBlocker (req, res, next) {
}
return next();
}
}