feat: implement whitelist for self-hosted instances (#3939)

* whitelist for username based endpoints

* added gist whitelist

* review

* fix

---------

Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
This commit is contained in:
Kyle Upton
2025-09-15 23:13:42 +03:00
committed by GitHub
co-authored by Alexandr
parent 70add4cfcf
commit 3987991058
11 changed files with 168 additions and 32 deletions
+18
View File
@@ -4,6 +4,7 @@ import {
renderError,
parseBoolean,
} from "../src/common/utils.js";
import { gistWhitelist } from "../src/common/whitelist.js";
import { isLocaleAvailable } from "../src/translations.js";
import { renderGistCard } from "../src/cards/gist.js";
import { fetchGist } from "../src/fetchers/gist.js";
@@ -26,6 +27,23 @@ export default async (req, res) => {
res.setHeader("Content-Type", "image/svg+xml");
if (gistWhitelist && !gistWhitelist.includes(id)) {
return res.send(
renderError(
"This gist ID is not whitelisted",
"Please deploy your own instance",
{
title_color,
text_color,
bg_color,
border_color,
theme,
show_repo_link: false,
},
),
);
}
if (locale && !isLocaleAvailable(locale)) {
return res.send(
renderError("Something went wrong", "Language not found", {
+31 -8
View File
@@ -1,5 +1,6 @@
import { renderStatsCard } from "../src/cards/stats.js";
import { blacklist } from "../src/common/blacklist.js";
import { whitelist } from "../src/common/whitelist.js";
import {
clampValue,
CONSTANTS,
@@ -41,15 +42,37 @@ export default async (req, res) => {
} = req.query;
res.setHeader("Content-Type", "image/svg+xml");
if (blacklist.includes(username)) {
if (whitelist && !whitelist.includes(username)) {
return res.send(
renderError("Something went wrong", "This username is blacklisted", {
title_color,
text_color,
bg_color,
border_color,
theme,
}),
renderError(
"This username is not whitelisted",
"Please deploy your own instance",
{
title_color,
text_color,
bg_color,
border_color,
theme,
show_repo_link: false,
},
),
);
}
if (whitelist === undefined && blacklist.includes(username)) {
return res.send(
renderError(
"This username is blacklisted",
"Please deploy your own instance",
{
title_color,
text_color,
bg_color,
border_color,
theme,
show_repo_link: false,
},
),
);
}
+31 -8
View File
@@ -1,5 +1,6 @@
import { renderRepoCard } from "../src/cards/repo.js";
import { blacklist } from "../src/common/blacklist.js";
import { whitelist } from "../src/common/whitelist.js";
import {
clampValue,
CONSTANTS,
@@ -29,15 +30,37 @@ export default async (req, res) => {
res.setHeader("Content-Type", "image/svg+xml");
if (blacklist.includes(username)) {
if (whitelist && !whitelist.includes(username)) {
return res.send(
renderError("Something went wrong", "This username is blacklisted", {
title_color,
text_color,
bg_color,
border_color,
theme,
}),
renderError(
"This username is not whitelisted",
"Please deploy your own instance",
{
title_color,
text_color,
bg_color,
border_color,
theme,
show_repo_link: false,
},
),
);
}
if (whitelist === undefined && blacklist.includes(username)) {
return res.send(
renderError(
"This username is blacklisted",
"Please deploy your own instance",
{
title_color,
text_color,
bg_color,
border_color,
theme,
show_repo_link: false,
},
),
);
}
+31 -8
View File
@@ -1,5 +1,6 @@
import { renderTopLanguages } from "../src/cards/top-languages.js";
import { blacklist } from "../src/common/blacklist.js";
import { whitelist } from "../src/common/whitelist.js";
import {
clampValue,
CONSTANTS,
@@ -36,15 +37,37 @@ export default async (req, res) => {
} = req.query;
res.setHeader("Content-Type", "image/svg+xml");
if (blacklist.includes(username)) {
if (whitelist && !whitelist.includes(username)) {
return res.send(
renderError("Something went wrong", "This username is blacklisted", {
title_color,
text_color,
bg_color,
border_color,
theme,
}),
renderError(
"This username is not whitelisted",
"Please deploy your own instance",
{
title_color,
text_color,
bg_color,
border_color,
theme,
show_repo_link: false,
},
),
);
}
if (whitelist === undefined && blacklist.includes(username)) {
return res.send(
renderError(
"This username is blacklisted",
"Please deploy your own instance",
{
title_color,
text_color,
bg_color,
border_color,
theme,
show_repo_link: false,
},
),
);
}
+18
View File
@@ -6,6 +6,7 @@ import {
parseBoolean,
renderError,
} from "../src/common/utils.js";
import { whitelist } from "../src/common/whitelist.js";
import { fetchWakatimeStats } from "../src/fetchers/wakatime.js";
import { isLocaleAvailable } from "../src/translations.js";
@@ -36,6 +37,23 @@ export default async (req, res) => {
res.setHeader("Content-Type", "image/svg+xml");
if (whitelist && !whitelist.includes(username)) {
return res.send(
renderError(
"This username is not whitelisted",
"Please deploy your own instance",
{
title_color,
text_color,
bg_color,
border_color,
theme,
show_repo_link: false,
},
),
);
}
if (locale && !isLocaleAvailable(locale)) {
return res.send(
renderError("Something went wrong", "Language not found", {