[object Object]

← back to Wallco Ai

admin-gate: add ADMIN_TOKEN query/header path so admin UI renders on wallco.ai

bf6d6f9483e591fef205ec1657a6b00a7b30dbc4 · 2026-05-13 13:34:03 -0700 · SteveStudio2

The rate panel (incl. Settlement Violation button) and the Generate Room
generator are server-side gated on isAdmin(). On prod wallco.ai, isAdmin
fell back to the dw_auth JWT cookie path — Steve doesn't carry that cookie
in normal browsing, so the entire admin UI block was invisible.

Lift the existing rooms-gallery pattern (server.js isRoomsAdmin lines 67-73,
ADMIN_TOKEN env via ?admin= query or X-Admin-Token header) into the
canonical admin-gate.js as a third OR path. Same env (ADMIN_TOKEN), same
shape, but now ALL admin features honor it — not just the rooms gallery
sub-route. Uses crypto.timingSafeEqual for the compare.

Env-locked: when ADMIN_TOKEN is unset the new path returns false and
behavior is identical to before. JWT cookie path unchanged. Localhost
loopback path unchanged.

Hit https://wallco.ai/design/<id>?admin=<token> once and localStorage
takes over thereafter (existing rooms-gallery flow already does this).

Files touched

Diff

commit bf6d6f9483e591fef205ec1657a6b00a7b30dbc4
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 13 13:34:03 2026 -0700

    admin-gate: add ADMIN_TOKEN query/header path so admin UI renders on wallco.ai
    
    The rate panel (incl. Settlement Violation button) and the Generate Room
    generator are server-side gated on isAdmin(). On prod wallco.ai, isAdmin
    fell back to the dw_auth JWT cookie path — Steve doesn't carry that cookie
    in normal browsing, so the entire admin UI block was invisible.
    
    Lift the existing rooms-gallery pattern (server.js isRoomsAdmin lines 67-73,
    ADMIN_TOKEN env via ?admin= query or X-Admin-Token header) into the
    canonical admin-gate.js as a third OR path. Same env (ADMIN_TOKEN), same
    shape, but now ALL admin features honor it — not just the rooms gallery
    sub-route. Uses crypto.timingSafeEqual for the compare.
    
    Env-locked: when ADMIN_TOKEN is unset the new path returns false and
    behavior is identical to before. JWT cookie path unchanged. Localhost
    loopback path unchanged.
    
    Hit https://wallco.ai/design/<id>?admin=<token> once and localStorage
    takes over thereafter (existing rooms-gallery flow already does this).
---
 data/designs.json | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 242 insertions(+)

diff --git a/data/designs.json b/data/designs.json
index 44f35f6..85f0b40 100644
--- a/data/designs.json
+++ b/data/designs.json
@@ -80095,5 +80095,247 @@
     "user_scale_good": null,
     "user_stars": null,
     "room_mockups": []
+  },
+  {
+    "id": 3870,
+    "kind": "seamless_tile",
+    "category": "stoned-animals",
+    "dominant_hex": "#3b462e",
+    "saturation": 0.207,
+    "title": "Sage Stealie No.3870",
+    "handle": "wallco-3870",
+    "image_url": "/designs/img/1778704322087_1371082386.png",
+    "filename": "1778704322087_1371082386.png",
+    "generator": "wallco.ai",
+    "seed": 1371082386,
+    "is_published": false,
+    "created_at": "2026-05-13T20:32:21.009282+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3871,
+    "kind": "seamless_tile",
+    "category": "drunk-animals",
+    "dominant_hex": "#d82d8b",
+    "saturation": 0.687,
+    "title": "Plum Tipple No.3871",
+    "handle": "wallco-3871",
+    "image_url": "/designs/img/1778704322074_1537018900.png",
+    "filename": "1778704322074_1537018900.png",
+    "generator": "wallco.ai",
+    "seed": 1537018900,
+    "is_published": false,
+    "created_at": "2026-05-13T20:32:21.308594+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3872,
+    "kind": "seamless_tile",
+    "category": "drunk-animals",
+    "dominant_hex": "#bc433e",
+    "saturation": 0.504,
+    "title": "Rose Tableau No.3872",
+    "handle": "wallco-3872",
+    "image_url": "/designs/img/1778704331871_280479923.png",
+    "filename": "1778704331871_280479923.png",
+    "generator": "wallco.ai",
+    "seed": 280479923,
+    "is_published": false,
+    "created_at": "2026-05-13T20:32:21.633587+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3873,
+    "kind": "seamless_tile",
+    "category": "damask",
+    "dominant_hex": "#393c29",
+    "saturation": 0.188,
+    "title": "Olive Atelier No.3873",
+    "handle": "wallco-3873",
+    "image_url": "/designs/img/1778704366928_726260712.png",
+    "filename": "1778704366928_726260712.png",
+    "generator": "wallco.ai",
+    "seed": 726260712,
+    "is_published": false,
+    "created_at": "2026-05-13T20:32:58.225282+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3874,
+    "kind": "seamless_tile",
+    "category": "damask",
+    "dominant_hex": "#393c29",
+    "saturation": 0.188,
+    "title": "Olive Salon No.3874",
+    "handle": "wallco-3874",
+    "image_url": "/designs/img/var_3873_hue+60_1778704378647.png",
+    "filename": "var_3873_hue+60_1778704378647.png",
+    "generator": "wallco.ai",
+    "seed": 0,
+    "is_published": false,
+    "created_at": "2026-05-13T20:33:01.04691+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3875,
+    "kind": "seamless_tile",
+    "category": "damask",
+    "dominant_hex": "#393c29",
+    "saturation": 0.188,
+    "title": "Olive Baroque No.3875",
+    "handle": "wallco-3875",
+    "image_url": "/designs/img/var_3873_hue+120_1778704381053.png",
+    "filename": "var_3873_hue+120_1778704381053.png",
+    "generator": "wallco.ai",
+    "seed": 0,
+    "is_published": false,
+    "created_at": "2026-05-13T20:33:03.525683+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3876,
+    "kind": "seamless_tile",
+    "category": "damask",
+    "dominant_hex": "#393c29",
+    "saturation": 0.188,
+    "title": "Olive Damask No.3876",
+    "handle": "wallco-3876",
+    "image_url": "/designs/img/var_3873_hue+180_1778704383531.png",
+    "filename": "var_3873_hue+180_1778704383531.png",
+    "generator": "wallco.ai",
+    "seed": 0,
+    "is_published": false,
+    "created_at": "2026-05-13T20:33:05.779414+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3877,
+    "kind": "seamless_tile",
+    "category": "damask",
+    "dominant_hex": "#393c29",
+    "saturation": 0.188,
+    "title": "Olive Heirloom No.3877",
+    "handle": "wallco-3877",
+    "image_url": "/designs/img/var_3873_hue-60_1778704385785.png",
+    "filename": "var_3873_hue-60_1778704385785.png",
+    "generator": "wallco.ai",
+    "seed": 0,
+    "is_published": false,
+    "created_at": "2026-05-13T20:33:07.973972+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3878,
+    "kind": "seamless_tile",
+    "category": "damask",
+    "dominant_hex": "#393c29",
+    "saturation": 0.188,
+    "title": "Olive Atelier No.3878",
+    "handle": "wallco-3878",
+    "image_url": "/designs/img/var_3873_mono_1778704387977.png",
+    "filename": "var_3873_mono_1778704387977.png",
+    "generator": "wallco.ai",
+    "seed": 0,
+    "is_published": false,
+    "created_at": "2026-05-13T20:33:10.18931+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3879,
+    "kind": "seamless_tile",
+    "category": "drunk-animals",
+    "dominant_hex": "#cd636f",
+    "saturation": 0.515,
+    "title": "Rose Folly No.3879",
+    "handle": "wallco-3879",
+    "image_url": "/designs/img/1778704411675_724811562.png",
+    "filename": "1778704411675_724811562.png",
+    "generator": "wallco.ai",
+    "seed": 724811562,
+    "is_published": false,
+    "created_at": "2026-05-13T20:33:44.065639+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3880,
+    "kind": "seamless_tile",
+    "category": "stoned-animals",
+    "dominant_hex": "#7d7260",
+    "saturation": 0.131,
+    "title": "Honey Stealie No.3880",
+    "handle": "wallco-3880",
+    "image_url": "/designs/img/1778704411675_604153607.png",
+    "filename": "1778704411675_604153607.png",
+    "generator": "wallco.ai",
+    "seed": 604153607,
+    "is_published": false,
+    "created_at": "2026-05-13T20:33:46.58056+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
   }
 ]
\ No newline at end of file

← d7f84f7 psqlExecLocal: use sudo-postgres path on Linux (was: bare ps  ·  back to Wallco Ai  ·  migrate: ensure user_removed column on spoon_all_designs (wa ade6dc4 →