@alliance-droid/status-feedback-system 4.3.0 → 4.3.1
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 +6 -0
- package/README.md +92 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.3.1
|
|
4
|
+
|
|
5
|
+
- Documentation: added a [4.3 consumer upgrade guide](README.md#upgrading-to-43) to the README shipped in the npm package. It identifies affected custom proxies, shows how to delegate tokens on board reads, and explains how to diagnose missing status controls.
|
|
6
|
+
- Corrected the documented Svelte minimum and clarified that consumer Admins and ProductOwners both need feedback-project assignments.
|
|
7
|
+
- Runtime behavior is unchanged from 4.3.0. Affected consumers must apply the proxy changes in their own app; installing this documentation patch does not modify host routes.
|
|
8
|
+
|
|
3
9
|
## 4.3.0
|
|
4
10
|
|
|
5
11
|
- Security: refreshed dependencies and raised the Svelte peer minimum to 5.55.7. The matching admin update requires feedback-scoped access tokens and explicit project assignments for consumer Admins as well as ProductOwners.
|
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Drop-in system status pages and user feedback components for SvelteKit apps.
|
|
|
4
4
|
|
|
5
5
|
This package provides UI components plus an optional SvelteKit server proxy for talking to a [status-feedback-admin](https://alliance.ghe.com/alliance/status-feedback-admin) backend. The admin app handles data storage, API key management, and the admin dashboard.
|
|
6
6
|
|
|
7
|
+
**Upgrading an existing app to 4.3?** Read [Upgrading to 4.3](#upgrading-to-43), especially if your proxy replaces a `server-delegated` placeholder with an access token. This guide is included in the installed package's `README.md`.
|
|
8
|
+
|
|
7
9
|
## Architecture
|
|
8
10
|
|
|
9
11
|
```
|
|
@@ -48,7 +50,7 @@ Log into the admin dashboard, create a project, and copy its API key (prefixed `
|
|
|
48
50
|
npm install @alliance-droid/status-feedback-system
|
|
49
51
|
```
|
|
50
52
|
|
|
51
|
-
**Peer dependencies:** `svelte ^5.
|
|
53
|
+
**Peer dependencies:** `svelte ^5.55.7`, `@alliance-droid/svelte-component-library >=1.3.2`
|
|
52
54
|
|
|
53
55
|
> `@alliance-droid/svelte-component-library` must be `>=1.3.2` — earlier versions are incompatible with Svelte `5.56+` and throw `target.exclude.has is not a function` when board components render.
|
|
54
56
|
|
|
@@ -82,6 +84,94 @@ Then point components at the same-origin route and omit `apiKey`:
|
|
|
82
84
|
|
|
83
85
|
Direct admin calls with `apiKey="sf_..."` remain supported for existing integrations, but the proxy is the hardened default.
|
|
84
86
|
|
|
87
|
+
## Upgrading to 4.3
|
|
88
|
+
|
|
89
|
+
### Which consumers need a change?
|
|
90
|
+
|
|
91
|
+
Version 4.3 discovers management permissions on **`GET /api/board`**. Earlier versions probed an item's `/transitions` endpoint after loading the board. The board now needs an authenticated list response containing `canManageStatus` and per-item `canChangeStatus` / `needsInput` fields before showing editable controls or the **Needs my input** filter.
|
|
92
|
+
|
|
93
|
+
| Integration | Required action |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| `createAuthTokenGetter()` or another real access-token getter with the package's 4.3 proxy | No additional proxy change for token forwarding. The package forwards the token on board reads automatically. Check the backend and access prerequisites below. |
|
|
96
|
+
| Direct admin calls with a real access-token getter | No custom proxy change. The 4.3 client sends the token on board reads; backend and access prerequisites still apply. |
|
|
97
|
+
| A custom proxy that forwards bearer tokens only on `/transitions` and `/status` | Also forward the user's bearer token on `GET /api/board`, including filtered and paginated reads. |
|
|
98
|
+
| A server-delegated proxy, such as SkyBridgeSPCC, with `getAuthToken: () => 'server-delegated'` | Replace the placeholder with the signed-in user's real access token on `GET /api/board` too. Passing the placeholder upstream makes the board read-only. |
|
|
99
|
+
| No management token getter | The board remains read-only for status management. Configure authenticated token delivery to enable manager controls. |
|
|
100
|
+
|
|
101
|
+
**Installing 4.3.1 provides these instructions; it does not update custom routes in consuming apps.** Apps using the affected patterns must update their proxy and deploy that app change.
|
|
102
|
+
|
|
103
|
+
### Fix a custom server-delegated proxy
|
|
104
|
+
|
|
105
|
+
In your app's catch-all feedback route (typically `src/routes/svc/feedback/[...path]/+server.ts`), extend the existing token-delegation wrapper to cover these requests:
|
|
106
|
+
|
|
107
|
+
| Request | Token handling |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| `GET api/board` | Attach the signed-in user's access token when available. Ordinary reads may continue without one; `status=needs_input` requires management access. |
|
|
110
|
+
| `GET api/board/feedback/:id/transitions` | Keep the existing authenticated transition lookup. |
|
|
111
|
+
| `PATCH api/board/feedback/:id/status` | Keep the existing authenticated mutation and same-origin protections. |
|
|
112
|
+
|
|
113
|
+
For a SkyBridgeSPCC-style wrapper, replace the status-only route predicate with:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import type { RequestEvent } from '@sveltejs/kit';
|
|
117
|
+
|
|
118
|
+
function statusTokenRequirement(event: RequestEvent): 'optional' | 'required' | null {
|
|
119
|
+
const method = event.request.method.toUpperCase();
|
|
120
|
+
const path = (event.params.path ?? '').replace(/^\/+|\/+$/g, '');
|
|
121
|
+
if (method === 'GET' && path === 'api/board') return 'optional';
|
|
122
|
+
if (
|
|
123
|
+
(method === 'GET' && /^api\/board\/feedback\/[^/]+\/transitions$/.test(path)) ||
|
|
124
|
+
(method === 'PATCH' && /^api\/board\/feedback\/[^/]+\/status$/.test(path))
|
|
125
|
+
) return 'required';
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
At the start of the existing delegation wrapper, use the classification to select the token. The following is a replacement fragment: `isSameOriginStatusRequest`, `forbiddenFeedbackResponse`, `resolveFeedbackUser`, and `mintStatusAccessToken` are your app's existing helpers, not package exports.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const requirement = statusTokenRequirement(event);
|
|
134
|
+
if (!requirement) return event;
|
|
135
|
+
|
|
136
|
+
const sameOrigin = isSameOriginStatusRequest(event);
|
|
137
|
+
if (!sameOrigin && requirement === 'required') return forbiddenFeedbackResponse();
|
|
138
|
+
if (!resolveFeedbackUser(event)) return event;
|
|
139
|
+
|
|
140
|
+
const accessToken = sameOrigin ? await mintStatusAccessToken(event) : null;
|
|
141
|
+
const headers = new Headers(event.request.headers);
|
|
142
|
+
if (accessToken) {
|
|
143
|
+
headers.set('Authorization', `Bearer ${accessToken}`);
|
|
144
|
+
} else {
|
|
145
|
+
headers.delete('Authorization');
|
|
146
|
+
}
|
|
147
|
+
// Continue with the existing code that clones event.request using these headers
|
|
148
|
+
// and passes the prepared event to the package proxy handler.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Ensure your exported **GET handler runs this wrapper for board reads**, as well as transitions. Keep the app's session and authorization checks. Your same-origin check must reject cross-site delegation; ordinary board reads without same-origin evidence can continue without a bearer token. Never fall back to the placeholder or a browser-supplied token when server delegation fails. The delegated token must represent the signed-in user, not an application client-credentials identity.
|
|
152
|
+
|
|
153
|
+
For a custom pass-through proxy, forward the real `Authorization` header instead of minting a token. Both patterns must preserve `status=needs_input`, `category`, `sort`, `limit`, and `offset`, return the capability fields unchanged, and avoid shared caching of authenticated board responses. The package's 4.3 proxy handles these details when your wrapper passes it the prepared event.
|
|
154
|
+
|
|
155
|
+
### Backend and access prerequisites
|
|
156
|
+
|
|
157
|
+
1. Apply the admin server's `20260908120000_response_source` migration before deploying the matching admin update. An older server does not return the new capability fields; upgrading the client alone cannot enable them.
|
|
158
|
+
2. Use Svelte `^5.55.7` and component library `>=1.3.2` in the consuming app.
|
|
159
|
+
3. Request an Alliance **access token** with audience and scope `status-feedback-admin`, a user subject (`sub`), client identity (`client_id`), expiration, and the intended role claims. An ID token or placeholder does not satisfy this contract. If scopes or refresh-token configuration changed, sign out and back in.
|
|
160
|
+
4. Provision the user in the feedback admin application and explicitly assign them to the feedback project. **Consumer Admins and ProductOwners both require project assignment.** Global administration through the admin dashboard's own session is separate.
|
|
161
|
+
|
|
162
|
+
### Check missing controls after upgrading
|
|
163
|
+
|
|
164
|
+
Inspect the JSON returned by your app's board request, such as `/svc/feedback/api/board?status=open`:
|
|
165
|
+
|
|
166
|
+
| Result | What to check |
|
|
167
|
+
| --- | --- |
|
|
168
|
+
| `data.canManageStatus` is absent | The app may point at an older server, or its proxy may be dropping the new fields. Check the actual `SF_API_URL` deployment. |
|
|
169
|
+
| `data.canManageStatus` is `false` | Check token delivery, token scope/audience/expiry, the user's role, and feedback-project assignment. Ordinary reads intentionally succeed even when optional authentication fails. |
|
|
170
|
+
| `data.canManageStatus` is `true`, but an item's `canChangeStatus` is `false` | That item's current workflow state has no consumer action available. Try an Open item to check the manager controls. |
|
|
171
|
+
| The **Needs my input** request returns 403 | The server did not authorize project management for that request. Check that the same token reaches filtered and paginated board reads. |
|
|
172
|
+
|
|
173
|
+
After updating the proxy, reload the board as an assigned Admin or ProductOwner. An actionable Open item should show the purple status control; **Needs my input** should be available. Also check an ordinary viewer still gets a read-only status badge.
|
|
174
|
+
|
|
85
175
|
## Components
|
|
86
176
|
|
|
87
177
|
### StatusPage
|
|
@@ -238,7 +328,7 @@ Categories are fixed by the system (**Bug**, **Feature Request**) — `categoryC
|
|
|
238
328
|
|
|
239
329
|
#### Setting status (ProductOwners and Admins)
|
|
240
330
|
|
|
241
|
-
When you pass `getAuthToken`, **Admins
|
|
331
|
+
When you pass `getAuthToken`, **Admins and ProductOwners assigned to the feedback project** can accept, reopen, or decline feedback (Won't do, Duplicate, Can't reproduce), where the current status permits the decision. Reopens and declines require a reason. **Only acceptance starts automation**; engineering, QA approval, release, and completion transitions remain in the admin app.
|
|
242
332
|
|
|
243
333
|
Editable items have **purple status controls and row accents**, accompanied by a text cue. The sidebar's **Needs my input** filter shows Open, Considering, and Waiting on reply, filtered on the server across all pages. Everyone continues to see each item's granular status.
|
|
244
334
|
|
package/package.json
CHANGED