/[sudobot]/trunk/src/api/controllers/ConfigController.ts
ViewVC logotype

Diff of /trunk/src/api/controllers/ConfigController.ts

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 370 by rakin, Mon Jul 29 17:29:50 2024 UTC revision 389 by rakin, Mon Jul 29 17:29:55 2024 UTC
# Line 1  Line 1 
1  import { dot, object } from "dot-object";  import { dot, object } from "dot-object";
2  import { body } from "express-validator";  import { body } from "express-validator";
3  import { z as zod, ZodSchema } from "zod";  import { z as zod } from "zod";
4  import KeyValuePair from "../../types/KeyValuePair";  import KeyValuePair from "../../types/KeyValuePair";
5  import Controller from "../Controller";  import Controller from "../Controller";
6  import RequireAuth from "../middleware/RequireAuth";  import RequireAuth from "../middleware/RequireAuth";
# Line 21  export default class ConfigController ex Line 21  export default class ConfigController ex
21          };          };
22      }      }
23    
24      private zodSchema() {      private zodSchema(id: string) {
25          const snowflake = zod.string().regex(/\d+/, { message: "The given value is not a Snowflake" });          const snowflake = zod.string().regex(/\d+/, { message: "The given value is not a Snowflake" });
26            const config = this.client.config.props[id];
27    
28          const schema = zod.object({          const schema = zod.object({
29              "prefix": zod.string().optional(),              "prefix": zod.string().optional(),
# Line 39  export default class ConfigController ex Line 40  export default class ConfigController ex
40              "role_commands": zod.record(              "role_commands": zod.record(
41                  snowflake,                  snowflake,
42                  zod.array(zod.string().min(1))                  zod.array(zod.string().min(1))
43              ).optional(),              ).optional().default({}),
44              "autoclear": zod.object({              "autoclear": zod.object({
45                  "enabled": zod.boolean().optional(),                  "enabled": zod.boolean().optional(),
46                  "channels": zod.array(snowflake).optional()                  "channels": zod.array(snowflake).optional().default(config.autoclear.channels)
47              }).optional(),              }).optional(),
48              "verification": zod.object({              "verification": zod.object({
49                  "enabled": zod.boolean().optional(),                  "enabled": zod.boolean().optional(),
# Line 66  export default class ConfigController ex Line 67  export default class ConfigController ex
67              }).optional(),              }).optional(),
68              "autorole": zod.object({              "autorole": zod.object({
69                  "enabled": zod.boolean().optional(),                  "enabled": zod.boolean().optional(),
70                  "roles": zod.array(snowflake).optional()                  "roles": zod.array(snowflake).optional().default(config.autorole.roles)
71              }).optional(),              }).optional(),
72              "spam_filter": zod.object({              "spam_filter": zod.object({
73                  "enabled": zod.boolean().optional(),                  "enabled": zod.boolean().optional(),
74                  "limit": zod.number().int().optional(),                  "limit": zod.number().int().optional(),
75                  "time": zod.number().optional(),                  "time": zod.number().optional(),
76                  "diff": zod.number().optional(),                  "diff": zod.number().optional(),
77                  "exclude": zod.array(snowflake).optional(),                  "exclude": zod.array(snowflake).optional().default(config.spam_filter.exclude),
78                  "samelimit": zod.number().int().optional(),                  "samelimit": zod.number().int().optional(),
79                  "unmute_in": zod.number().optional()                  "unmute_in": zod.number().optional()
80              }).optional(),              }).optional(),
# Line 81  export default class ConfigController ex Line 82  export default class ConfigController ex
82                  "enabled": zod.boolean().optional(),                  "enabled": zod.boolean().optional(),
83                  "max_joins": zod.number().int().optional(),                  "max_joins": zod.number().int().optional(),
84                  "time": zod.number().optional(),                  "time": zod.number().optional(),
85                  "channels": zod.array(snowflake).optional(),                  "channels": zod.array(snowflake).optional().default(config.raid.channels),
86                  "exclude": zod.boolean().optional()                  "exclude": zod.boolean().optional()
87              }).optional(),              }).optional(),
88              "global_commands": zod.array(zod.string()).optional(),              "global_commands": zod.array(zod.string()).optional().default(config.global_commands),
89              "filters": zod.object({              "filters": zod.object({
90                  "ignore_staff": zod.boolean().optional(),                  "ignore_staff": zod.boolean().optional(),
91                  "chars_repeated": zod.number().int().optional(),                  "chars_repeated": zod.number().int().optional(),
92                  "words_repeated": zod.number().int().optional(),                  "words_repeated": zod.number().int().optional(),
93                  "words": zod.array(zod.string()).optional(),                  "words": zod.array(zod.string()).optional().default(config.filters.words),
94                  "tokens": zod.array(zod.string()).optional(),                  "tokens": zod.array(zod.string()).optional().default(config.filters.tokens),
95                  "invite_message": zod.string().optional(),                  "invite_message": zod.string().optional(),
96                  "words_excluded": zod.array(snowflake).optional(),                  "words_excluded": zod.array(snowflake).optional().default(config.filters.words_excluded),
97                  "domain_excluded": zod.array(snowflake).optional(),                  "domain_excluded": zod.array(snowflake).optional().default(config.filters.domain_excluded),
98                  "invite_excluded": zod.array(snowflake).optional(),                  "invite_excluded": zod.array(snowflake).optional().default(config.filters.invite_excluded),
99                  "words_enabled": zod.boolean().optional(),                  "words_enabled": zod.boolean().optional(),
100                  "invite_enabled": zod.boolean().optional(),                  "invite_enabled": zod.boolean().optional(),
101                  "domain_enabled": zod.boolean().optional(),                  "domain_enabled": zod.boolean().optional(),
102                  "regex": zod.boolean().optional(),                  "regex": zod.boolean().optional(),
103                  "file_mimes_excluded": zod.array(zod.string()).optional(),                  "file_mimes_excluded": zod.array(zod.string()).optional().default(config.filters.file_mimes_excluded),
104                  "file_types_excluded": zod.array(zod.string()).optional(),                  "file_types_excluded": zod.array(zod.string()).optional().default(config.filters.file_types_excluded),
105                  "domains": zod.array(zod.string()).optional(),                  "domains": zod.array(zod.string()).optional().default(config.filters.domains),
106                  "regex_patterns": zod.array(zod.string()).optional(),                  "regex_patterns": zod.array(zod.string()).optional().default(config.filters.regex_patterns),
107                  "rickrolls_enabled": zod.boolean().optional(),                  "rickrolls_enabled": zod.boolean().optional(),
108                  "pings": zod.number().int().optional()                  "pings": zod.number().int().optional()
109              }).optional()              }).optional()
# Line 127  export default class ConfigController ex Line 128  export default class ConfigController ex
128    
129      public async update(request: Request) {      public async update(request: Request) {
130          const { id } = request.params;          const { id } = request.params;
131          const { config } = request.body;          const { config: origconfig } = request.body;
132    
133          console.log(config);                  console.log(origconfig);        
134    
135            try {
136                const currentConfigDotObject = this.client.config.props[id];
137        
138                console.log("Current config: ", currentConfigDotObject);
139    
140                const result = this.zodSchema(id).safeParse(object(origconfig));
141    
142                if (!result?.success) {
143                    return this.response({ error: "The data schema does not match.", error_type: 'validation', errors: result.error.errors }, 422);
144                }
145    
146                const config = result.data;
147                const newConfig = merge.withOptions({ mergeArrays: false }, currentConfigDotObject, config);
148                const result2 = this.zodSchema(id).safeParse(newConfig);
149    
150                if (!result2?.success) {
151                    console.log(result2.error.errors);                
152                    return this.response({ error: 'Internal Server Error (500)', error_type: 'internal' }, 500);
153                }
154    
155                console.log('Final', newConfig);
156                this.client.config.props[id] = newConfig;
157                this.client.config.write();      
158                return { message: "Configuration updated", previous: dot(currentConfigDotObject), new: dot(this.client.config.props[id]) };    
159            }
160            catch (e) {
161                console.log(e);
162                return this.response({ error: 'Internal Server Error', error_type: 'internal' }, 500);
163            }
164        }
165    
166        public async update2(request: Request) {
167            const { id } = request.params;
168            const { config: origconfig } = request.body;
169    
170            console.log(origconfig);        
171    
172          try {          try {
173              const currentConfigDotObject = dot(this.client.config.props[id]);              const currentConfigDotObject = dot(this.client.config.props[id]);
174              let newConfigDotObject = {...currentConfigDotObject};              let newConfigDotObject = {...currentConfigDotObject};
175            
176              console.log("Input: ", config);              console.log("Current config: ", currentConfigDotObject);
177    
178              const result = this.zodSchema().safeParse(object({...config}));              const result = this.zodSchema(id).safeParse(object({...origconfig}));
179    
180              if (!result?.success) {              if (!result?.success) {
181                  return this.response({ error: "The data schema does not match.", error_type: 'validation', errors: result.error.errors }, 422);                  return this.response({ error: "The data schema does not match.", error_type: 'validation', errors: result.error.errors }, 422);
182              }              }
183    
184              for (const configKey in config) {              const config = result.data;
185    
186                console.log(config);            
187    
188                for (const key in config) {
189                    const configKey = key as keyof typeof config;
190                  const regexMatched = /(.+)\[\d+\]/g.test(configKey);                  const regexMatched = /(.+)\[\d+\]/g.test(configKey);
191                                    
192                  if (typeof currentConfigDotObject[configKey] === 'undefined' && !regexMatched) {                  if (typeof currentConfigDotObject[configKey] === 'undefined' && !regexMatched) {
193                      return this.response({ error: `The key '${configKey}' is not allowed` }, 422);                      console.log(configKey, config[configKey]);
194                        
195                        if (currentConfigDotObject[configKey] instanceof Array && config[configKey] instanceof Array) {
196                            console.log('Array');                        
197                        }
198                        else
199                            return this.response({ error: `The key '${configKey}' is not allowed` }, 422);
200                  }                  }
201    
202                  if (!regexMatched && config[configKey] !== null && config[configKey] !== null && typeof config[configKey] !== typeof currentConfigDotObject[configKey]) {                  if (!regexMatched && config[configKey] !== null && config[configKey] !== null && typeof config[configKey] !== typeof currentConfigDotObject[configKey]) {
203                      console.log(typeof config[configKey], typeof currentConfigDotObject[configKey]);                          console.log(typeof config[configKey], typeof currentConfigDotObject[configKey]);    
204                                            
205                      if (typeof currentConfigDotObject[configKey] === 'number' && typeof config[configKey] === 'string') {                      if (typeof currentConfigDotObject[configKey] === 'number' && typeof config[configKey] === 'string') {
206                          const int = parseInt(config[configKey]);                          const int = parseInt(config[configKey]!.toString());
207    
208                          if (int !== NaN) {                          if (int !== NaN) {
209                              newConfigDotObject[configKey] = int;                              newConfigDotObject[configKey] = int;
# Line 169  export default class ConfigController ex Line 218  export default class ConfigController ex
218                  console.log("Updating: ", configKey, config[configKey], newConfigDotObject[configKey]);                  console.log("Updating: ", configKey, config[configKey], newConfigDotObject[configKey]);
219              }              }
220    
221                const newObj = object({...newConfigDotObject});
222                const configObj = object({...config});
223    
224                // console.log("Newobj", newObj);
225                // console.log("Configobj", configObj);
226    
227              newConfigDotObject = merge.withOptions({ mergeArrays: false }, object({...newConfigDotObject}), object({...config}));              newConfigDotObject = merge.withOptions({ mergeArrays: false }, newObj, configObj);
228              console.log("Output: ", newConfigDotObject);              console.log("Output: ", newConfigDotObject);
229    
230              this.client.config.props[id] = newConfigDotObject;              this.client.config.props[id] = newConfigDotObject;

Legend:
Removed from v.370  
changed lines
  Added in v.389

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26