diff options
author | Chris Chrome <christophercookman@gmail.com> | 2022-08-13 00:24:39 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-13 00:24:39 -0600 |
commit | a7565ea37d80d45c613093048b5bf89ae49457e5 (patch) | |
tree | cc545cc3a6b4fc9c8112b9daa7ff76dc26f0d528 /api | |
parent | Update index.ts (diff) | |
parent | Handle avatar uploads (diff) | |
download | server-a7565ea37d80d45c613093048b5bf89ae49457e5.tar.xz |
Merge pull request #830 from fosscord/dev/applications
Bot control panel
Diffstat (limited to 'api')
-rw-r--r-- | api/client_test/developers.html | 76 | ||||
-rw-r--r-- | api/src/routes/applications/#id/bot/index.ts | 83 | ||||
-rw-r--r-- | api/src/routes/applications/#id/index.ts | 30 | ||||
-rw-r--r-- | api/src/routes/applications/#id/skus.ts | 11 | ||||
-rw-r--r-- | api/src/routes/applications/index.ts | 27 |
5 files changed, 188 insertions, 39 deletions
diff --git a/api/client_test/developers.html b/api/client_test/developers.html index 2a4402d7..87595e77 100644 --- a/api/client_test/developers.html +++ b/api/client_test/developers.html @@ -1,42 +1,44 @@ <!DOCTYPE html> <html class="theme-dark" data-theme="dark"> - <head> - <meta charset="utf-8" /> - <meta content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no" name="viewport" /> - <link rel="stylesheet" href="/assets/532.03aaeef88460fae60534.css" integrity="" /> - <link rel="icon" href="/assets/07dca80a102d4149e9736d4b162cff6f.ico" /> - <title>Discord Test Client Developer Portal</title> - <meta charset="utf-8" data-react-helmet="true" /> - </head> +<head> + <meta charset="utf-8" /> + <meta content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no" name="viewport" /> - <body> - <div id="app-mount"></div> - <script> - window.GLOBAL_ENV = { - API_VERSION: 9, - API_ENDPOINT: "/api", - WEBAPP_ENDPOINT: "", - CDN_HOST: `${location.hostname}:3003`, + <link rel="stylesheet" href="/assets/532.03aaeef88460fae60534.css" integrity="" /> + <link rel="icon" href="/assets/07dca80a102d4149e9736d4b162cff6f.ico" /> + <title>Discord Test Client Developer Portal</title> + <meta charset="utf-8" data-react-helmet="true" /> +</head> - BRAINTREE_KEY: "production_5st77rrc_49pp2rp4phym7387", - STRIPE_KEY: "pk_live_CUQtlpQUF0vufWpnpUmQvcdi", - MARKETING_ENDPOINT: "//discord.com", - RELEASE_CHANNEL: "stable", - ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0" - }; - GLOBAL_ENV.MEDIA_PROXY_ENDPOINT = location.protocol + "//" + GLOBAL_ENV.CDN_HOST; - const localStorage = window.localStorage; - // TODO: remote auth - // window.GLOBAL_ENV.REMOTE_AUTH_ENDPOINT = window.GLOBAL_ENV.GATEWAY_ENDPOINT.replace(/wss?:/, ""); - localStorage.setItem("gatewayURL", window.GLOBAL_ENV.GATEWAY_ENDPOINT); - localStorage.setItem( - "DeveloperOptionsStore", - `{"trace":false,"canary":false,"logGatewayEvents":true,"logOverlayEvents":true,"logAnalyticsEvents":true,"sourceMapsEnabled":false,"axeEnabled":false}` - ); - </script> - <script src="/assets/41fde19fdf180f3d4315.js" integrity=""></script> - <script src="/assets/7b04a3ab10e05dd9054e.js" integrity=""></script> - <script src="/assets/d1f811da193e5648048b.js" integrity=""></script> - </body> -</html> +<body> + <div id="app-mount"></div> + <script> + window.GLOBAL_ENV = { + API_VERSION: 9, + API_ENDPOINT: "/api", + WEBAPP_ENDPOINT: "", + CDN_HOST: `${location.hostname}:3003`, + + BRAINTREE_KEY: "production_5st77rrc_49pp2rp4phym7387", + STRIPE_KEY: "pk_live_CUQtlpQUF0vufWpnpUmQvcdi", + MARKETING_ENDPOINT: "//discord.com", + RELEASE_CHANNEL: "stable", + ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0" + }; + GLOBAL_ENV.MEDIA_PROXY_ENDPOINT = location.protocol + "//" + GLOBAL_ENV.CDN_HOST; + const localStorage = window.localStorage; + // TODO: remote auth + // window.GLOBAL_ENV.REMOTE_AUTH_ENDPOINT = window.GLOBAL_ENV.GATEWAY_ENDPOINT.replace(/wss?:/, ""); + localStorage.setItem("gatewayURL", window.GLOBAL_ENV.GATEWAY_ENDPOINT); + localStorage.setItem( + "DeveloperOptionsStore", + `{"trace":false,"canary":false,"logGatewayEvents":true,"logOverlayEvents":true,"logAnalyticsEvents":true,"sourceMapsEnabled":false,"axeEnabled":false}` + ); + </script> + <script src="/assets/38f40c32d3c8a2fdf73b.js" integrity=""></script> + <script src="/assets/aa190934324e05fcc35c.js" integrity=""></script> + <script src="/assets/45664a0209e828a528b4.js" integrity=""></script> +</body> + +</html> \ No newline at end of file diff --git a/api/src/routes/applications/#id/bot/index.ts b/api/src/routes/applications/#id/bot/index.ts new file mode 100644 index 00000000..562c31fe --- /dev/null +++ b/api/src/routes/applications/#id/bot/index.ts @@ -0,0 +1,83 @@ +import { Request, Response, Router } from "express"; +import { route } from "@fosscord/api"; +import { Application, Config, FieldErrors, generateToken, OrmUtils, Snowflake, trimSpecial, User, handleFile } from "@fosscord/util"; +import { HTTPError } from "lambert-server"; +import { verifyToken } from "node-2fa"; + +const router: Router = Router(); + +router.post("/", route({}), async (req: Request, res: Response) => { + const app = await Application.findOne({where: {id: req.params.id}}); + if(!app) return res.status(404); + const username = trimSpecial(app.name); + const discriminator = await User.generateDiscriminator(username); + if (!discriminator) { + // We've failed to generate a valid and unused discriminator + throw FieldErrors({ + username: { + code: "USERNAME_TOO_MANY_USERS", + message: req?.t("auth:register.USERNAME_TOO_MANY_USERS"), + }, + }); + } + + const user = OrmUtils.mergeDeep(new User(), { + created_at: new Date(), + username: username, + discriminator, + id: app.id, + bot: true, + system: false, + premium_since: 0, + desktop: false, + mobile: false, + premium: false, + premium_type: 0, + bio: app.description, + mfa_enabled: true, + totp_secret: "", + totp_backup_codes: [], + verified: true, + disabled: false, + deleted: false, + email: null, + rights: Config.get().register.defaultRights, + nsfw_allowed: true, + public_flags: "0", + flags: "0", + data: { + hash: null, + valid_tokens_since: new Date(), + }, + settings: {}, + extended_settings: {}, + fingerprints: [], + notes: {}, + }); + await user.save(); + app.bot = user; + await app.save(); + res.send().status(204) +}); + +router.post("/reset", route({}), async (req: Request, res: Response) => { + let bot = await User.findOne({where: {id: req.params.id}}); + let owner = await User.findOne({where: {id: req.user_id}}); + if(!bot) return res.status(404); + if(owner?.totp_secret && (!req.body.code || verifyToken(owner.totp_secret, req.body.code))) { + throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); + } + bot.data = { hash: undefined, valid_tokens_since: new Date() }; + await bot.save(); + let token = await generateToken(bot.id); + res.json({token}).status(200); +}); + +router.patch("/", route({}), async (req: Request, res: Response) => { + if (req.body.avatar) req.body.avatar = await handleFile(`/avatars/${req.params.id}`, req.body.avatar as string); + let app = OrmUtils.mergeDeep(await User.findOne({where: {id: req.params.id}}), req.body); + await app.save(); + res.json(app).status(200); +}); + +export default router; \ No newline at end of file diff --git a/api/src/routes/applications/#id/index.ts b/api/src/routes/applications/#id/index.ts new file mode 100644 index 00000000..0aced582 --- /dev/null +++ b/api/src/routes/applications/#id/index.ts @@ -0,0 +1,30 @@ +import { Request, Response, Router } from "express"; +import { route } from "@fosscord/api"; +import { Application, OrmUtils, Team, trimSpecial, User } from "@fosscord/util"; + +const router: Router = Router(); + +router.get("/", route({}), async (req: Request, res: Response) => { + let results = await Application.findOne({where: {id: req.params.id}, relations: ["owner", "bot"] }); + res.json(results).status(200); +}); + +router.patch("/", route({}), async (req: Request, res: Response) => { + delete req.body.icon; + let app = OrmUtils.mergeDeep(await Application.findOne({where: {id: req.params.id}, relations: ["owner", "bot"]}), req.body); + if(app.bot) { + app.bot.bio = req.body.description + app.bot?.save(); + } + if(req.body.tags) app.tags = req.body.tags; + await app.save(); + res.json(app).status(200); +}); + +router.post("/delete", route({}), async (req: Request, res: Response) => { + await Application.delete(req.params.id); + res.send().status(200); +}); + + +export default router; \ No newline at end of file diff --git a/api/src/routes/applications/#id/skus.ts b/api/src/routes/applications/#id/skus.ts new file mode 100644 index 00000000..5b667f36 --- /dev/null +++ b/api/src/routes/applications/#id/skus.ts @@ -0,0 +1,11 @@ +import { Request, Response, Router } from "express"; +import { route } from "@fosscord/api"; +import { Application, OrmUtils, Team, trimSpecial, User } from "@fosscord/util"; + +const router: Router = Router(); + +router.get("/", route({}), async (req: Request, res: Response) => { + res.json([]).status(200); +}); + +export default router; \ No newline at end of file diff --git a/api/src/routes/applications/index.ts b/api/src/routes/applications/index.ts index 28ce42da..033dcc51 100644 --- a/api/src/routes/applications/index.ts +++ b/api/src/routes/applications/index.ts @@ -1,11 +1,34 @@ import { Request, Response, Router } from "express"; import { route } from "@fosscord/api"; +import { Application, OrmUtils, Team, trimSpecial, User } from "@fosscord/util"; const router: Router = Router(); +export interface ApplicationCreateSchema { + name: string; + team_id?: string | number; +} + router.get("/", route({}), async (req: Request, res: Response) => { //TODO - res.send([]).status(200); + let results = await Application.find({where: {owner: {id: req.user_id}}, relations: ["owner", "bot"] }); + res.json(results).status(200); +}); + +router.post("/", route({}), async (req: Request, res: Response) => { + const body = req.body as ApplicationCreateSchema; + const user = await User.findOne({where: {id: req.user_id}}) + if(!user) res.status(420); + let app = OrmUtils.mergeDeep(new Application(), { + name: trimSpecial(body.name), + description: "", + bot_public: true, + owner: user, + verify_key: "IMPLEMENTME", + flags: 0 + }); + await app.save(); + res.json(app).status(200); }); -export default router; +export default router; \ No newline at end of file |