@zerotal/admin 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,28 @@ follows the Zerotal monorepo's unified versioning.
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [1.6.0] — 2026-08-15
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **The environment badge showed on every screen, and always said the same thing.** It read
|
|
16
|
+
`APP_ENV`, which holds the runtime mode once the app has booted — so it rendered `web`,
|
|
17
|
+
which is in nobody's quiet list, and its `staging` tone could never fire. A badge whose
|
|
18
|
+
whole purpose is preventing "I thought this was staging" was displaying the same wrong word
|
|
19
|
+
in every environment. It reads `deployEnv()` now, so local stays quiet and staging is
|
|
20
|
+
visibly staging.
|
|
21
|
+
|
|
22
|
+
## [1.5.1] — 2026-08-15
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- **The development bypass never applied.** `AdminGuardMiddleware` and the `ability` helper
|
|
27
|
+
both read `APP_ENV` to decide whether this was a development environment — but by the time
|
|
28
|
+
either runs, `setAppEnv()` has replaced it with the runtime mode. So the panel refused
|
|
29
|
+
access in development exactly as it does in production, which is not what either was
|
|
30
|
+
written to do. Both ask `devSurfacesEnabled()` now, and both still fail closed anywhere
|
|
31
|
+
that is not explicitly a development environment.
|
|
32
|
+
|
|
11
33
|
## [1.5.0] — 2026-08-15
|
|
12
34
|
|
|
13
35
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerotal/admin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"maturity": "stable",
|
|
6
6
|
"private": false,
|
|
@@ -31,16 +31,16 @@
|
|
|
31
31
|
"typecheck": "tsc --noEmit"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@zerotal/cache": "1.
|
|
35
|
-
"@zerotal/core": "1.
|
|
36
|
-
"@zerotal/flow": "1.
|
|
37
|
-
"@zerotal/flow-ui": "1.
|
|
38
|
-
"@zerotal/validator": "1.
|
|
34
|
+
"@zerotal/cache": "1.6.0",
|
|
35
|
+
"@zerotal/core": "1.6.0",
|
|
36
|
+
"@zerotal/flow": "1.6.0",
|
|
37
|
+
"@zerotal/flow-ui": "1.6.0",
|
|
38
|
+
"@zerotal/validator": "1.6.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@zerotal/orm": "1.
|
|
42
|
-
"@zerotal/auth": "1.
|
|
43
|
-
"@zerotal/queue": "1.
|
|
41
|
+
"@zerotal/orm": "1.6.0",
|
|
42
|
+
"@zerotal/auth": "1.6.0",
|
|
43
|
+
"@zerotal/queue": "1.6.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@zerotal/orm": "^1.0.0",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseMiddleware,
|
|
1
|
+
import { BaseMiddleware, devSurfacesEnabled } from "@zerotal/core";
|
|
2
2
|
import type { NextFn, HttpContext } from "@zerotal/core";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -19,7 +19,9 @@ export class AdminGuardMiddleware extends BaseMiddleware {
|
|
|
19
19
|
protected options = {};
|
|
20
20
|
|
|
21
21
|
async handle(_http: HttpContext, next: NextFn): Promise<Response | void> {
|
|
22
|
-
|
|
22
|
+
// `devSurfacesEnabled()` — `APP_ENV` holds the runtime mode by now, so reading it
|
|
23
|
+
// directly asked whether "web" is a development environment and always said no.
|
|
24
|
+
if (devSurfacesEnabled()) return next();
|
|
23
25
|
return new Response(
|
|
24
26
|
"Admin panel is not accessible: no authentication is configured.\n" +
|
|
25
27
|
"Set `middleware` in config/admin.ts to a real auth guard before exposing it.\n",
|
package/src/support/ability.ts
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* put a page in the sidebar, but it cannot put one in front of a production user
|
|
21
21
|
* who has no authorization configured.
|
|
22
22
|
*/
|
|
23
|
-
import { tryCurrentApp,
|
|
23
|
+
import { tryCurrentApp, devSurfacesEnabled } from "@zerotal/core";
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* The slice of `@zerotal/auth`'s `GateService` the panel uses. Declared locally
|
|
@@ -69,5 +69,5 @@ export async function resolveAbility(
|
|
|
69
69
|
return false;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
return
|
|
72
|
+
return devSurfacesEnabled();
|
|
73
73
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// admin panel ecosystem grows a plugin for exactly this.
|
|
7
7
|
|
|
8
8
|
import type { HtmlNode } from "@zerotal/flow";
|
|
9
|
+
import { deployEnv } from "@zerotal/core";
|
|
9
10
|
import type { RenderHook } from "../renderHooks.ts";
|
|
10
11
|
|
|
11
12
|
export interface EnvironmentIndicatorOptions {
|
|
@@ -41,7 +42,12 @@ export function environmentIndicator(options: EnvironmentIndicatorOptions = {}):
|
|
|
41
42
|
const tones = { ...DEFAULT_TONES, ...(options.tones ?? {}) };
|
|
42
43
|
|
|
43
44
|
return (): HtmlNode | null => {
|
|
44
|
-
|
|
45
|
+
// `deployEnv()` — `APP_ENV` holds the runtime mode by the time a page renders, so
|
|
46
|
+
// this badge read "web": never in the quiet list, so it showed on every screen
|
|
47
|
+
// including local, and its `staging` tone could never fire. The one mistake this
|
|
48
|
+
// component exists to prevent is editing production believing it is staging, and
|
|
49
|
+
// a badge that always says the same wrong word prevents nothing.
|
|
50
|
+
const env = (options.environment ?? deployEnv()).trim();
|
|
45
51
|
if (!env || quiet.has(env.toLowerCase())) return null;
|
|
46
52
|
|
|
47
53
|
const tone = tones[env.toLowerCase()] ?? "bg-amber-500 text-black";
|