1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-11-06 19:02:33 +01:00

Merge pull request #540 from Thesourtimes/master

General work on API
This commit is contained in:
Samuel 2021-12-20 14:56:53 +01:00 committed by GitHub
commit dc9c18411e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1995 additions and 392 deletions

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Fosscord Documentation
url: https://docs.fosscord.com/
about: Need documentation and examples for the Fosscord? Head over to Fosscord's official documentation.
- name: Discord's Developer Documentation
url: https://discord.com/developers/docs/intro
about: Need help with the Discord resources? Head here instead of asking on Fosscord!
- name: Fosscord' Official Discord server
url: https://discord.com/invite/Ms5Ev7S6bF
about: Need help with the server? Talk with us in our official server.

View File

@ -1,4 +1,8 @@
MONGO_URL=mongodb://localhost/fosscord MONGO_URL=mongodb://localhost/fosscord
PORT=3001 PORT=3001
PRODUCTION=TRUE PRODUCTION=TRUE
THREADS=# automatically use all available cores, only available if production = true THREADS=# automatically use all available cores, only available if production = true
#LOG_REQUESTS=
# only log 200 and 204: LOG_REQUESTS=200 204
# log everything except 200 and 204: LOG_REQUESTS=-200 204
# log all requests: LOG_REQUESTS=-

2180
api/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -84,6 +84,7 @@
"missing-native-js-functions": "^1.2.18", "missing-native-js-functions": "^1.2.18",
"morgan": "^1.10.0", "morgan": "^1.10.0",
"multer": "^1.4.2", "multer": "^1.4.2",
"nanocolors": "^0.2.13",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"patch-package": "^6.4.7", "patch-package": "^6.4.7",
"proxy-agent": "^5.0.0", "proxy-agent": "^5.0.0",

View File

@ -26,5 +26,6 @@ DROP TABLE webhooks;
DROP TABLE channels; DROP TABLE channels;
DROP TABLE members; DROP TABLE members;
DROP TABLE guilds; DROP TABLE guilds;
DROP TABLE client_relase;
-- DROP TABLE users; -- DROP TABLE users;
-- DROP TABLE config; -- DROP TABLE config;

View File

@ -12,6 +12,7 @@ import { initTranslation } from "./middlewares/Translation";
import morgan from "morgan"; import morgan from "morgan";
import { initInstance } from "./util/Instance"; import { initInstance } from "./util/Instance";
import { registerRoutes } from "@fosscord/util"; import { registerRoutes } from "@fosscord/util";
import { red } from "nanocolors"
export interface FosscordServerOptions extends ServerOptions {} export interface FosscordServerOptions extends ServerOptions {}
@ -38,17 +39,6 @@ export class FosscordServer extends Server {
await initEvent(); await initEvent();
await initInstance(); await initInstance();
/*
DOCUMENTATION: uses LOG_REQUESTS environment variable
# only log 200 and 204
LOG_REQUESTS=200 204
# log everything except 200 and 204
LOG_REQUESTS=-200 204
# log all requests
LOG_REQUESTS=-
*/
let logRequests = process.env["LOG_REQUESTS"] != undefined; let logRequests = process.env["LOG_REQUESTS"] != undefined;
if (logRequests) { if (logRequests) {
this.app.use( this.app.use(
@ -60,7 +50,7 @@ export class FosscordServer extends Server {
} }
}) })
); );
} };
this.app.use(CORS); this.app.use(CORS);
this.app.use(BodyParser({ inflate: true, limit: "10mb" })); this.app.use(BodyParser({ inflate: true, limit: "10mb" }));
@ -85,19 +75,20 @@ export class FosscordServer extends Server {
}); });
this.app = app; this.app = app;
//app.use("/__development", )
//app.use("/__internals", )
app.use("/api/v6", api); app.use("/api/v6", api);
app.use("/api/v7", api); app.use("/api/v7", api);
app.use("/api/v8", api); app.use("/api/v8", api);
app.use("/api/v9", api); app.use("/api/v9", api);
app.use("/api", api); // allow unversioned requests app.use("/api", api); // allow unversioned requests
this.app.use(ErrorHandler); this.app.use(ErrorHandler);
TestClient(this.app); TestClient(this.app);
if (logRequests) { if (logRequests) console.log(red(`Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!`));
console.log(
"Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!"
);
}
return super.start(); return super.start();
} }
} };

View File

@ -3,25 +3,27 @@ import { HTTPError } from "lambert-server";
import { checkToken, Config, Rights } from "@fosscord/util"; import { checkToken, Config, Rights } from "@fosscord/util";
export const NO_AUTHORIZATION_ROUTES = [ export const NO_AUTHORIZATION_ROUTES = [
//Authentication routes // Authentication routes
"/auth/login", "/auth/login",
"/auth/register", "/auth/register",
"/auth/location-metadata", "/auth/location-metadata",
//Routes with a seperate auth system // Routes with a seperate auth system
"/webhooks/", "/webhooks/",
//Public information endpoints // Public information endpoints
"/ping", "/ping",
"/gateway", "/gateway",
"/experiments", "/experiments",
//Public kubernetes integration "/updates",
"/downloads/",
// Public kubernetes integration
"/-/readyz", "/-/readyz",
"/-/healthz", "/-/healthz",
//Client nalytics // Client analytics
"/science", "/science",
"/track", "/track",
//Public policy pages // Public policy pages
"/policies/instance", "/policies/instance",
//Asset delivery // Asset delivery
/\/guilds\/\d+\/widget\.(json|png)/ /\/guilds\/\d+\/widget\.(json|png)/
]; ];

View File

@ -84,12 +84,15 @@ export default function TestClient(app: Application) {
return res.send(buffer); return res.send(buffer);
}); });
app.get("*", (req: Request, res: Response) => { app.get("*", (req: Request, res: Response) => {
const { useTestClient } = Config.get().client;
res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24); res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24);
res.set("content-type", "text/html"); res.set("content-type", "text/html");
if(req.url.startsWith("/api")) return; if(req.url.startsWith("/api") || req.url.startsWith("/__development")) return;
if (req.url.startsWith("/invite")) return res.send(html.replace("9b2b7f0632acd0c5e781", "9f24f709a3de09b67c49"));
if(!useTestClient) return res.send("Test client is disabled on this instance. Use a stand-alone client to connect this instance.")
if (req.url.startsWith("/invite")) return res.send(html.replace("9b2b7f0632acd0c5e781", "9f24f709a3de09b67c49"));
res.send(html); res.send(html);
}); });
} }

View File

@ -0,0 +1,20 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Relase, Config } from "@fosscord/util";
const router = Router();
router.get("/:branch", route({}), async (req: Request, res: Response) => {
const { client } = Config.get();
const { branch } = req.params;
const { platform } = req.query;
//TODO
if(!platform || !["linux", "osx", "win"].includes(platform.toString())) return res.status(404)
const relase = await Relase.findOneOrFail({ name: client.relases.upstreamVersion });
res.redirect(relase[`win_url`]);
});
export default router;

View File

@ -0,0 +1,20 @@
import { Guild, Config } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
const { limit, personalization_disabled } = req.params;
var showAllGuilds = Config.get().guild.showAllGuildsInDiscovery;
// ! this only works using SQL querys
// TODO: implement this with default typeorm query
// const guilds = await Guild.find({ where: { features: "DISCOVERABLE" } }); //, take: Math.abs(Number(limit)) });
const guilds = showAllGuilds
? await Guild.find({ take: Math.abs(Number(limit || 20)) })
: await Guild.find({ where: `"features" LIKE '%COMMUNITY%'`, take: Math.abs(Number(limit || 100)) });
res.send({ recommended_guilds: guilds });
});
export default router;

20
api/src/routes/updates.ts Normal file
View File

@ -0,0 +1,20 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Config, Relase } from "@fosscord/util";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
const { client } = Config.get();
const relase = await Relase.findOneOrFail({ name: client.relases.upstreamVersion})
res.json({
name: relase.name,
pub_date: relase.pub_date,
url: relase.url,
notes: relase.notes
});
});
export default router;

20
nginx.conf Normal file
View File

@ -0,0 +1,20 @@
# This is an example
server {
server_name fosscord.example.com;
listen 80;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $host;
proxy_pass_request_headers on;
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_no_cache 1;
proxy_cache_bypass 1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

View File

@ -2,6 +2,7 @@ import { Column, Entity } from "typeorm";
import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass"; import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
import crypto from "crypto"; import crypto from "crypto";
import { Snowflake } from "../util/Snowflake"; import { Snowflake } from "../util/Snowflake";
import { SessionsReplace } from "..";
@Entity("config") @Entity("config")
export class ConfigEntity extends BaseClassWithoutId { export class ConfigEntity extends BaseClassWithoutId {
@ -48,6 +49,11 @@ export interface ConfigValue {
endpointPublic: string | null; endpointPublic: string | null;
endpointPrivate: string | null; endpointPrivate: string | null;
}; };
api: {
defaultVersion: string;
activeVersions: string[];
useFosscordEnhancements: boolean;
};
general: { general: {
instanceName: string; instanceName: string;
instanceDescription: string | null; instanceDescription: string | null;
@ -172,6 +178,16 @@ export interface ConfigValue {
allowTemplateCreation: Boolean; allowTemplateCreation: Boolean;
allowDiscordTemplates: Boolean; allowDiscordTemplates: Boolean;
allowRaws: Boolean; allowRaws: Boolean;
},
client: {
useTestClient: Boolean;
relases: {
useLocalRelases: Boolean; //TODO
upstreamVersion: string;
}
},
metrics: {
timeout: number;
} }
} }
@ -186,6 +202,11 @@ export const DefaultConfigOptions: ConfigValue = {
endpointPrivate: null, endpointPrivate: null,
endpointPublic: null, endpointPublic: null,
}, },
api: {
defaultVersion: "9",
activeVersions: ["6", "7", "8", "9"],
useFosscordEnhancements: true,
},
general: { general: {
instanceName: "Fosscord Instance", instanceName: "Fosscord Instance",
instanceDescription: "This is a Fosscord instance made in pre-relase days", instanceDescription: "This is a Fosscord instance made in pre-relase days",
@ -346,5 +367,15 @@ export const DefaultConfigOptions: ConfigValue = {
allowTemplateCreation: true, allowTemplateCreation: true,
allowDiscordTemplates: true, allowDiscordTemplates: true,
allowRaws: false allowRaws: false
},
client: {
useTestClient: true,
relases: {
useLocalRelases: true,
upstreamVersion: "0.0.264"
}
},
metrics: {
timeout: 30000
} }
}; };

View File

@ -0,0 +1,26 @@
import { Column, Entity} from "typeorm";
import { BaseClass } from "./BaseClass";
@Entity("client_relase")
export class Relase extends BaseClass {
@Column()
name: string;
@Column()
pub_date: string;
@Column()
url: string;
@Column()
deb_url: string;
@Column()
osx_url: string;
@Column()
win_url: string;
@Column({ nullable: true })
notes?: string;
}

View File

@ -26,3 +26,4 @@ export * from "./Template";
export * from "./User"; export * from "./User";
export * from "./VoiceState"; export * from "./VoiceState";
export * from "./Webhook"; export * from "./Webhook";
export * from "./clientRelase";