Close the last three UI leftovers: shared staff HTML, cookie domain, stock Swagger label.
Some checks are pending
offline / test (push) Waiting to run
Some checks are pending
offline / test (push) Waiting to run
verae-staff-ui holds one review template for CS and access-staff. Staff cookies take STAFF_COOKIE_DOMAIN for a reverse-proxy host. /docs stays vendor Swagger with an integrator banner only.
This commit is contained in:
parent
b68fefdea8
commit
d8efffe8be
23 changed files with 368 additions and 44 deletions
|
|
@ -7,3 +7,25 @@ Shared cookie login for CS / sales / accounting / access-staff HTML.
|
|||
Port `:3027`. Set `STAFF_AUTH=1` on the department servers and `STAFF_SESSION_URL=http://127.0.0.1:3027`. Cookie host is the browser host (ports share `127.0.0.1`). JSON APIs stay open unless you also send `x-staff-key`.
|
||||
|
||||
Default key: `STAFF_KEY` or `ADMIN_KEY` or `admin-dev-key`.
|
||||
|
||||
## Multiple hostnames
|
||||
|
||||
Cookies are host-scoped. On one operator box (`127.0.0.1`) that is enough. For several DNS names, put one reverse proxy in front and set `STAFF_COOKIE_DOMAIN`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name staff.example.com;
|
||||
location /session/ { proxy_pass http://127.0.0.1:3027/; }
|
||||
location /cs/ { proxy_pass http://127.0.0.1:3011/; }
|
||||
location /sales/ { proxy_pass http://127.0.0.1:3012/; }
|
||||
location /acct/ { proxy_pass http://127.0.0.1:3013/; }
|
||||
location /staff/ { proxy_pass http://127.0.0.1:3025/; }
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
STAFF_COOKIE_DOMAIN=.example.com
|
||||
STAFF_COOKIE_SECURE=1
|
||||
STAFF_SESSION_URL=https://staff.example.com/session
|
||||
STAFF_AUTH=1
|
||||
```
|
||||
|
|
|
|||
|
|
@ -9,7 +9,11 @@ export function sessionToken() {
|
|||
}
|
||||
|
||||
export function cookieHeader() {
|
||||
return `staff_session=${sessionToken()}; Path=/; HttpOnly; SameSite=Lax; Max-Age=86400`;
|
||||
let s = `staff_session=${sessionToken()}; Path=/; HttpOnly; SameSite=Lax; Max-Age=86400`;
|
||||
const domain = process.env.STAFF_COOKIE_DOMAIN;
|
||||
if (domain) s += `; Domain=${domain}`;
|
||||
if (process.env.STAFF_COOKIE_SECURE === '1') s += '; Secure';
|
||||
return s;
|
||||
}
|
||||
|
||||
export function cookieOk(req) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { sessionToken, cookieOk, headerOk } from '../src/token.js';
|
||||
import { sessionToken, cookieOk, headerOk, cookieHeader } from '../src/token.js';
|
||||
|
||||
test('cookie matches HMAC of staff key', () => {
|
||||
const tok = sessionToken();
|
||||
|
|
@ -9,3 +9,11 @@ test('cookie matches HMAC of staff key', () => {
|
|||
assert.equal(cookieOk({ headers: { cookie: 'staff_session=nope' } }), false);
|
||||
assert.equal(headerOk({ headers: { 'x-staff-key': process.env.STAFF_KEY || 'admin-dev-key' } }), true);
|
||||
});
|
||||
|
||||
test('cookie Domain is optional', () => {
|
||||
delete process.env.STAFF_COOKIE_DOMAIN;
|
||||
assert.equal(cookieHeader().includes('Domain='), false);
|
||||
process.env.STAFF_COOKIE_DOMAIN = '.example.com';
|
||||
assert.match(cookieHeader(), /Domain=\.example.com/);
|
||||
delete process.env.STAFF_COOKIE_DOMAIN;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue