update admin panel, api, and shared-types
This commit is contained in:
@@ -176,27 +176,25 @@ export class AdminMiscController {
|
||||
|
||||
// The mobile home slider ("اسلایدر موبایل") is stored under the same
|
||||
// `Setting` table as every other `const/:key` entry (key: mobile_main_slider),
|
||||
// but it gets its own permission (`custom.config.statics.slider`, per
|
||||
// acl.constants.ts / permissionConst.ts) rather than the broad `config.statics`
|
||||
// that guards the rest of the "مدیریت ثابت ها" screen — uploading/replacing the
|
||||
// public site banner is more sensitive than editing brand/tag lists, so it
|
||||
// should not be reachable by everyone who can merely open that screen.
|
||||
// and is open to everyone who can use the "مدیریت ثابت ها" screen
|
||||
// (`config.statics`). The older `custom.config.statics.slider` rid stays in
|
||||
// the catalogue so roles that still hold it keep saving, but gates nothing.
|
||||
// Routes declared ahead of `const/:key` so Nest doesn't match `const/slider`
|
||||
// (the legacy REST shape) to the generic key handler instead.
|
||||
@Get('const/slider')
|
||||
@RequirePermission('custom.config.statics.slider')
|
||||
@RequirePermission('config.statics')
|
||||
getSlider() {
|
||||
return this.misc.getConst('mobile_main_slider');
|
||||
}
|
||||
|
||||
@Put('const/slider')
|
||||
@RequirePermission('custom.config.statics.slider')
|
||||
@RequirePermission('config.statics')
|
||||
setSlider(@Body() body: Record<string, unknown>) {
|
||||
return this.misc.setConst('mobile_main_slider', body.val !== undefined ? body.val : body);
|
||||
}
|
||||
|
||||
@Delete('const/slider')
|
||||
@RequirePermission('custom.config.statics.slider')
|
||||
@RequirePermission('config.statics')
|
||||
removeSlider() {
|
||||
return this.misc.removeConst('mobile_main_slider');
|
||||
}
|
||||
@@ -223,11 +221,8 @@ export class AdminMiscController {
|
||||
return this.misc.removeConst(key);
|
||||
}
|
||||
|
||||
// Blocks the generic `config.statics`-gated routes from reaching the slider
|
||||
// setting by its raw key — otherwise anyone with `config.statics` could
|
||||
// bypass the dedicated `const/slider` routes (guarded by the stricter
|
||||
// `custom.config.statics.slider`) simply by calling `const/mobile_main_slider`
|
||||
// directly, since the underlying Setting row is keyed the same either way.
|
||||
// Keys with a dedicated route are refused here so each has exactly one way
|
||||
// in: the slider (`const/slider`) and the accounting and pricing settings.
|
||||
private assertNotSliderKey(key: string) {
|
||||
if (key === 'mobile_main_slider' || isAccountingSettingKey(key) || key.trim().toLowerCase().startsWith(PRICING_SETTING_PREFIX)) {
|
||||
throw new ForbiddenException('این تنظیم فقط از مسیر اختصاصی خود قابل دسترسی است');
|
||||
|
||||
@@ -6,8 +6,8 @@ import { Public } from '../auth/guards';
|
||||
* Public read of the admin-managed home slider ("اسلایدر موبایل" in
|
||||
* manage/Const.vue), served at GET /api/home/slider.
|
||||
*
|
||||
* The admin write path (const/slider, guarded by the dedicated
|
||||
* `custom.config.statics.slider` permission — see admin-misc.controller.ts)
|
||||
* The admin write path (const/slider, guarded by `config.statics` — see
|
||||
* admin-misc.controller.ts)
|
||||
* stores it under the same `Setting` row (key: mobile_main_slider) that this
|
||||
* reads. Split into its own controller/prefix, rather than exposing it under
|
||||
* `admin/misc`, so the shopper-facing site does not call an `/admin/...` path
|
||||
|
||||
Reference in New Issue
Block a user