/[sudobot]/branches/4.x/src/api/controllers/ConfigController.ts
ViewVC logotype

Contents of /branches/4.x/src/api/controllers/ConfigController.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 6965 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 /**
2 * This file is part of SudoBot.
3 *
4 * Copyright (C) 2021-2022 OSN Inc.
5 *
6 * SudoBot is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * SudoBot is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 import { dot, object } from "dot-object";
21 import { body } from "express-validator";
22 import KeyValuePair from "../../types/KeyValuePair";
23 import Controller from "../Controller";
24 import RequireAuth from "../middleware/RequireAuth";
25 import ValidatorError from "../middleware/ValidatorError";
26 import Request from "../Request";
27 import merge from 'ts-deepmerge';
28
29 export default class ConfigController extends Controller {
30 globalMiddleware(): Function[] {
31 return [RequireAuth, ValidatorError];
32 }
33
34 middleware(): KeyValuePair<Function[]> {
35 return {
36 update: [
37 body(["config"]).isObject()
38 ]
39 };
40 }
41
42 private zodSchema(id: string) {
43 const config = this.client.config.props[id];
44 return this.client.config.schema(config);
45 }
46
47 public async index(request: Request) {
48 const { id } = request.params;
49
50 if (!request.user?.guilds.includes(id)) {
51 return this.response({ error: "You don't have permission to access configuration of this guild." }, 403);
52 }
53
54 if (id === "global" || !this.client.config.props[id]) {
55 return this.response({ error: "No configuration found for the given guild ID" }, 404);
56 }
57
58 return this.client.config.props[id];
59 }
60
61 public async update(request: Request) {
62 const { id } = request.params;
63 const { config: origconfig } = request.body;
64
65 console.log(origconfig);
66
67 try {
68 const currentConfigDotObject = this.client.config.props[id];
69
70 console.log("Current config: ", currentConfigDotObject);
71
72 const result = this.zodSchema(id).safeParse(object(origconfig));
73
74 if (!result?.success) {
75 return this.response({ error: "The data schema does not match.", error_type: 'validation', errors: result.error.errors }, 422);
76 }
77
78 const config = result.data;
79 const newConfig = merge.withOptions({ mergeArrays: false }, currentConfigDotObject, config);
80 const result2 = this.zodSchema(id).safeParse(newConfig);
81
82 if (!result2?.success) {
83 console.log(result2.error.errors);
84 return this.response({ error: 'Internal Server Error (500)', error_type: 'internal' }, 500);
85 }
86
87 console.log('Final', newConfig);
88 this.client.config.props[id] = newConfig;
89 this.client.config.write();
90 return { message: "Configuration updated", previous: dot(currentConfigDotObject), new: dot(this.client.config.props[id]) };
91 }
92 catch (e) {
93 console.log(e);
94 return this.response({ error: 'Internal Server Error', error_type: 'internal' }, 500);
95 }
96 }
97
98 public async update2(request: Request) {
99 const { id } = request.params;
100 const { config: origconfig } = request.body;
101
102 console.log(origconfig);
103
104 try {
105 const currentConfigDotObject = dot(this.client.config.props[id]);
106 let newConfigDotObject = {...currentConfigDotObject};
107
108 console.log("Current config: ", currentConfigDotObject);
109
110 const result = this.zodSchema(id).safeParse(object({...origconfig}));
111
112 if (!result?.success) {
113 return this.response({ error: "The data schema does not match.", error_type: 'validation', errors: result.error.errors }, 422);
114 }
115
116 const config = result.data;
117
118 console.log(config);
119
120 for (const key in config) {
121 const configKey = key as keyof typeof config;
122 const regexMatched = /(.+)\[\d+\]/g.test(configKey);
123
124 if (typeof currentConfigDotObject[configKey] === 'undefined' && !regexMatched) {
125 console.log(configKey, config[configKey]);
126
127 if (currentConfigDotObject[configKey] instanceof Array && config[configKey] instanceof Array) {
128 console.log('Array');
129 }
130 else
131 return this.response({ error: `The key '${configKey}' is not allowed` }, 422);
132 }
133
134 if (!regexMatched && config[configKey] !== null && config[configKey] !== null && typeof config[configKey] !== typeof currentConfigDotObject[configKey]) {
135 console.log(typeof config[configKey], typeof currentConfigDotObject[configKey]);
136
137 if (typeof currentConfigDotObject[configKey] === 'number' && typeof config[configKey] === 'string') {
138 const int = parseInt(config[configKey]!.toString());
139
140 if (!isNaN(int)) {
141 newConfigDotObject[configKey] = int;
142 console.log("Updating: ", configKey, config[configKey], newConfigDotObject[configKey]);
143 continue;
144 }
145 }
146
147 return this.response({ error: `The key '${configKey}' has incompatible value type '${config[configKey] === null ? 'null' : typeof config[configKey]}'` }, 422);
148 }
149
150 console.log("Updating: ", configKey, config[configKey], newConfigDotObject[configKey]);
151 }
152
153 const newObj = object({...newConfigDotObject});
154 const configObj = object({...config});
155
156 // console.log("Newobj", newObj);
157 // console.log("Configobj", configObj);
158
159 newConfigDotObject = merge.withOptions({ mergeArrays: false }, newObj, configObj);
160 console.log("Output: ", newConfigDotObject);
161
162 this.client.config.props[id] = newConfigDotObject;
163 this.client.config.write();
164
165 return { message: "Configuration updated", previous: currentConfigDotObject, new: dot(this.client.config.props[id]) };
166 }
167 catch (e) {
168 console.log(e);
169 return this.response({ error: 'Internal Server Error', error_type: 'internal' }, 500);
170 }
171 }
172 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26