()
| 175 | class SystemConfigHandler extends SystemHandler { |
| 176 | @requireSudo |
| 177 | async get() { |
| 178 | this.response.template = 'manage_config.html'; |
| 179 | let value = this.ctx.setting.configSource; |
| 180 | |
| 181 | const processNode = (node: any, schema: Schema<any, any>, parent?: any, accessKey?: string) => { |
| 182 | if (!node) return; |
| 183 | if (['union', 'intersect'].includes(schema.type)) { |
| 184 | for (const item of schema.list) processNode(node, item, parent, accessKey); |
| 185 | } |
| 186 | if (parent && (schema.meta.secret === true || schema.meta.role === 'secret')) { |
| 187 | if (schema.type === 'string') parent[accessKey] = '[hidden]'; |
| 188 | // TODO support more types |
| 189 | } |
| 190 | if (schema.type === 'object') { |
| 191 | for (const key in schema.dict) processNode(node[key], schema.dict[key], node, key); |
| 192 | } |
| 193 | }; |
| 194 | |
| 195 | try { |
| 196 | const temp = yaml.load(this.ctx.setting.configSource); |
| 197 | for (const schema of this.ctx.setting.settings) processNode(temp, schema); |
| 198 | value = yaml.dump(temp); |
| 199 | } catch (e) { |
| 200 | logger.error('Failed to process config', e.message); |
| 201 | } |
| 202 | this.response.body = { |
| 203 | schema: Schema.intersect(this.ctx.setting.settings).toJSON(), |
| 204 | value, |
| 205 | }; |
| 206 | } |
| 207 | |
| 208 | @requireSudo |
| 209 | @param('value', Types.String) |
nothing calls this directly
no test coverage detected