feat: add api prefix option
This commit is contained in:
parent
899f743ed6
commit
b40ed5ce49
9 changed files with 27 additions and 22 deletions
|
@ -81,3 +81,6 @@ LIGHTWEIGHT_DB_PORT=
|
||||||
LIGHTWEIGHT_DB_USER=
|
LIGHTWEIGHT_DB_USER=
|
||||||
LIGHTWEIGHT_DB_PASSWORD=
|
LIGHTWEIGHT_DB_PASSWORD=
|
||||||
LIGHTWEIGHT_DB_DATABASE=
|
LIGHTWEIGHT_DB_DATABASE=
|
||||||
|
|
||||||
|
# If you want to add a prefix to API paths, such as /api, you can set that here
|
||||||
|
LIGHTWEIGHT_API_PATH_PREFIX=
|
||||||
|
|
|
@ -3,15 +3,15 @@ import moment from "moment-timezone";
|
||||||
import { GuildArchives } from "../data/GuildArchives";
|
import { GuildArchives } from "../data/GuildArchives";
|
||||||
import { notFound } from "./responses";
|
import { notFound } from "./responses";
|
||||||
|
|
||||||
export function initArchives(app: express.Express) {
|
export function initArchives(router: express.Router) {
|
||||||
const archives = new GuildArchives(null);
|
const archives = new GuildArchives(null);
|
||||||
|
|
||||||
// Legacy redirect
|
// Legacy redirect
|
||||||
app.get("/spam-logs/:id", (req: Request, res: Response) => {
|
router.get("/spam-logs/:id", (req: Request, res: Response) => {
|
||||||
res.redirect("/archives/" + req.params.id);
|
res.redirect("/archives/" + req.params.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/archives/:id", async (req: Request, res: Response) => {
|
router.get("/archives/:id", async (req: Request, res: Response) => {
|
||||||
const archive = await archives.find(req.params.id);
|
const archive = await archives.find(req.params.id);
|
||||||
if (!archive) return notFound(res);
|
if (!archive) return notFound(res);
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,8 @@ function simpleDiscordAPIRequest(bearerToken, path): Promise<any> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initAuth(app: express.Express) {
|
export function initAuth(router: express.Router) {
|
||||||
app.use(passport.initialize());
|
router.use(passport.initialize());
|
||||||
|
|
||||||
passport.serializeUser((user, done) => done(null, user));
|
passport.serializeUser((user, done) => done(null, user));
|
||||||
passport.deserializeUser((user, done) => done(null, user as IPassportApiUser));
|
passport.deserializeUser((user, done) => done(null, user as IPassportApiUser));
|
||||||
|
@ -110,8 +110,8 @@ export function initAuth(app: express.Express) {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
app.get("/auth/login", passport.authenticate("oauth2"));
|
router.get("/auth/login", passport.authenticate("oauth2"));
|
||||||
app.get(
|
router.get(
|
||||||
"/auth/oauth-callback",
|
"/auth/oauth-callback",
|
||||||
passport.authenticate("oauth2", { failureRedirect: "/", session: false }),
|
passport.authenticate("oauth2", { failureRedirect: "/", session: false }),
|
||||||
(req: Request, res: Response) => {
|
(req: Request, res: Response) => {
|
||||||
|
@ -122,7 +122,7 @@ export function initAuth(app: express.Express) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
app.post("/auth/validate-key", async (req: Request, res: Response) => {
|
router.post("/auth/validate-key", async (req: Request, res: Response) => {
|
||||||
const key = req.body.key;
|
const key = req.body.key;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
return res.status(400).json({ error: "No key supplied" });
|
return res.status(400).json({ error: "No key supplied" });
|
||||||
|
@ -135,14 +135,14 @@ export function initAuth(app: express.Express) {
|
||||||
|
|
||||||
res.json({ valid: true, userId });
|
res.json({ valid: true, userId });
|
||||||
});
|
});
|
||||||
app.post("/auth/logout", ...apiTokenAuthHandlers(), async (req: Request, res: Response) => {
|
router.post("/auth/logout", ...apiTokenAuthHandlers(), async (req: Request, res: Response) => {
|
||||||
await apiLogins.expireApiKey(req.user!.apiKey);
|
await apiLogins.expireApiKey(req.user!.apiKey);
|
||||||
return ok(res);
|
return ok(res);
|
||||||
});
|
});
|
||||||
|
|
||||||
// API route to refresh the given API token's expiry time
|
// API route to refresh the given API token's expiry time
|
||||||
// The actual refreshing happens in the api-token passport strategy above, so we just return 200 OK here
|
// The actual refreshing happens in the api-token passport strategy above, so we just return 200 OK here
|
||||||
app.post("/auth/refresh", ...apiTokenAuthHandlers(), (req, res) => {
|
router.post("/auth/refresh", ...apiTokenAuthHandlers(), (req, res) => {
|
||||||
return ok(res);
|
return ok(res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,10 +97,10 @@ function formatZodConfigSchema(schema: z.ZodTypeAny) {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initDocs(app: express.Express) {
|
export function initDocs(router: express.Router) {
|
||||||
const docsPluginNames = Object.keys(guildPluginInfo).filter((k) => guildPluginInfo[k].showInDocs);
|
const docsPluginNames = Object.keys(guildPluginInfo).filter((k) => guildPluginInfo[k].showInDocs);
|
||||||
|
|
||||||
app.get("/docs/plugins", (req: express.Request, res: express.Response) => {
|
router.get("/docs/plugins", (req: express.Request, res: express.Response) => {
|
||||||
res.json(
|
res.json(
|
||||||
docsPluginNames.map((pluginName) => {
|
docsPluginNames.map((pluginName) => {
|
||||||
const info = guildPluginInfo[pluginName];
|
const info = guildPluginInfo[pluginName];
|
||||||
|
@ -113,7 +113,7 @@ export function initDocs(app: express.Express) {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/docs/plugins/:pluginName", (req: express.Request, res: express.Response) => {
|
router.get("/docs/plugins/:pluginName", (req: express.Request, res: express.Response) => {
|
||||||
const name = req.params.pluginName;
|
const name = req.params.pluginName;
|
||||||
const baseInfo = guildPluginInfo[name];
|
const baseInfo = guildPluginInfo[name];
|
||||||
if (!baseInfo) {
|
if (!baseInfo) {
|
||||||
|
|
|
@ -3,12 +3,12 @@ import { apiTokenAuthHandlers } from "../auth";
|
||||||
import { initGuildsImportExportAPI } from "./importExport";
|
import { initGuildsImportExportAPI } from "./importExport";
|
||||||
import { initGuildsMiscAPI } from "./misc";
|
import { initGuildsMiscAPI } from "./misc";
|
||||||
|
|
||||||
export function initGuildsAPI(app: express.Express) {
|
export function initGuildsAPI(router: express.Router) {
|
||||||
const guildRouter = express.Router();
|
const guildRouter = express.Router();
|
||||||
guildRouter.use(...apiTokenAuthHandlers());
|
guildRouter.use(...apiTokenAuthHandlers());
|
||||||
|
|
||||||
initGuildsMiscAPI(guildRouter);
|
initGuildsMiscAPI(guildRouter);
|
||||||
initGuildsImportExportAPI(guildRouter);
|
initGuildsImportExportAPI(guildRouter);
|
||||||
|
|
||||||
app.use("/guilds", guildRouter);
|
router.use("/guilds", guildRouter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import { initGuildsAPI } from "./guilds/index";
|
||||||
import { clientError, error, notFound } from "./responses";
|
import { clientError, error, notFound } from "./responses";
|
||||||
import { startBackgroundTasks } from "./tasks";
|
import { startBackgroundTasks } from "./tasks";
|
||||||
|
|
||||||
|
const apiPathPrefix = env.HOST_MODE === "lightweight" ? env.LIGHTWEIGHT_API_PATH_PREFIX || "" : "/api";
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
|
@ -24,16 +26,20 @@ app.use(
|
||||||
);
|
);
|
||||||
app.use(multer().none());
|
app.use(multer().none());
|
||||||
|
|
||||||
|
const rootRouter = express.Router();
|
||||||
|
|
||||||
initAuth(app);
|
initAuth(app);
|
||||||
initGuildsAPI(app);
|
initGuildsAPI(app);
|
||||||
initArchives(app);
|
initArchives(app);
|
||||||
initDocs(app);
|
initDocs(app);
|
||||||
|
|
||||||
// Default route
|
// Default route
|
||||||
app.get("/", (req, res) => {
|
rootRouter.get("/", (req, res) => {
|
||||||
res.json({ status: "cookies", with: "milk" });
|
res.json({ status: "cookies", with: "milk" });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.use(apiPathPrefix, rootRouter);
|
||||||
|
|
||||||
// Error response
|
// Error response
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
app.use((err, req, res, next) => {
|
app.use((err, req, res, next) => {
|
||||||
|
|
|
@ -47,6 +47,8 @@ const envType = z.object({
|
||||||
LIGHTWEIGHT_DB_PASSWORD: z.string().optional(),
|
LIGHTWEIGHT_DB_PASSWORD: z.string().optional(),
|
||||||
LIGHTWEIGHT_DB_DATABASE: z.string().optional(),
|
LIGHTWEIGHT_DB_DATABASE: z.string().optional(),
|
||||||
|
|
||||||
|
LIGHTWEIGHT_API_PATH_PREFIX: z.string().optional(),
|
||||||
|
|
||||||
HOST_MODE: z.enum(["development", "standalone", "lightweight"]).optional().default("lightweight"),
|
HOST_MODE: z.enum(["development", "standalone", "lightweight"]).optional().default("lightweight"),
|
||||||
DEBUG: z
|
DEBUG: z
|
||||||
.string()
|
.string()
|
||||||
|
|
|
@ -15,9 +15,6 @@ server {
|
||||||
}
|
}
|
||||||
|
|
||||||
location /api {
|
location /api {
|
||||||
# Remove /api/ from the beginning when passing the path to the API process
|
|
||||||
rewrite /api(/.*)$ $1 break;
|
|
||||||
|
|
||||||
resolver 127.0.0.11;
|
resolver 127.0.0.11;
|
||||||
proxy_pass $backend_upstream$uri$is_args$args;
|
proxy_pass $backend_upstream$uri$is_args$args;
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
|
|
|
@ -15,9 +15,6 @@ server {
|
||||||
}
|
}
|
||||||
|
|
||||||
location /api {
|
location /api {
|
||||||
# Remove /api/ from the beginning when passing the path to the API process
|
|
||||||
rewrite /api(/.*)$ $1 break;
|
|
||||||
|
|
||||||
resolver 127.0.0.11;
|
resolver 127.0.0.11;
|
||||||
proxy_pass $backend_upstream$uri$is_args$args;
|
proxy_pass $backend_upstream$uri$is_args$args;
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
|
|
Loading…
Add table
Reference in a new issue