@7365admin1/core 3.64.5-staging.308 → 3.64.5-staging.310
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 +215 -0
- package/package.json +1 -1
- package/.changeset/member-duplicate-400.md +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,220 @@
|
|
|
1
1
|
# @iservice365/core
|
|
2
2
|
|
|
3
|
+
## 3.68.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1d5050b: Re-inviting the same person to the same app, organisation and site now re-sends the pending invitation instead of adding a duplicate; invite request logs no longer record the invitee's e-mail address.
|
|
8
|
+
|
|
9
|
+
## 3.68.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- d9e0ded: A duplicate membership insert now returns 400 "The user is already a member of this organization." instead of a 500.
|
|
14
|
+
|
|
15
|
+
## 3.68.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 689b152: POST /api/people: count cross-client person creation (gate ships switched off)
|
|
20
|
+
|
|
21
|
+
The signed-in branch of `POST /api/people` checked only that somebody was signed
|
|
22
|
+
in. The site and organisation came straight from the request body, and where that
|
|
23
|
+
body carries an e-mail, a password and a resident/tenant type, the service goes on
|
|
24
|
+
to create a **user account** and an **active membership** as well as the person row.
|
|
25
|
+
|
|
26
|
+
`site.people` is the collection every site-reach decision on the platform reads its
|
|
27
|
+
verdict from, so a row written there is not an ordinary record — it manufactures
|
|
28
|
+
reach into another client's estate.
|
|
29
|
+
|
|
30
|
+
This adds the site-reach check the camera, HID and people-list paths already use,
|
|
31
|
+
behind `PEOPLE_CREATE_REACH_MODE`, and **ships it in `log` mode**: it records what
|
|
32
|
+
it would refuse and refuses nothing. `enforce` refuses; `off` does not look. Any
|
|
33
|
+
unexpected error allows the request — this must never be why a real registration
|
|
34
|
+
fails.
|
|
35
|
+
|
|
36
|
+
It ships off because of RP-5. A person row carries no `createdBy`, so who created
|
|
37
|
+
the existing rows cannot be established retrospectively and the true refusal count
|
|
38
|
+
is only knowable from live traffic. Measured read-only on staging: 372
|
|
39
|
+
`site.people` rows, of which exactly **1** is self-signup shaped (`platform:
|
|
40
|
+
"mobile"`, `status: "pending"`) and 371 were written by a signed-in caller, across
|
|
41
|
+
3 of 256 sites.
|
|
42
|
+
|
|
43
|
+
Pre-login self-signup is untouched in every mode: a request with no session takes
|
|
44
|
+
the other branch of `add` before this runs, and that route is already constrained
|
|
45
|
+
by its own allow-list schema with `status` and `platform` pinned server-side.
|
|
46
|
+
|
|
47
|
+
## 3.68.0
|
|
48
|
+
|
|
49
|
+
### Minor Changes
|
|
50
|
+
|
|
51
|
+
- d7e9298: Manpower live status: an authenticated namespace beside the open one
|
|
52
|
+
|
|
53
|
+
`/manpower` streams every client site's live staffing level — how many guards are
|
|
54
|
+
actually on shift against how many were promised — to anyone who connects, with no
|
|
55
|
+
credential of any kind.
|
|
56
|
+
|
|
57
|
+
This adds `/manpower-live`, carrying exactly the same `manpower-status-update`
|
|
58
|
+
events, which admits a socket only when the handshake presents a session id that
|
|
59
|
+
resolves to a live session. Every refusal is an identical `Unauthorized`, and a
|
|
60
|
+
session store that is down refuses rather than letting everyone in.
|
|
61
|
+
|
|
62
|
+
`/manpower` itself is deliberately unchanged: the Capacitor guard app installed on
|
|
63
|
+
phones today and the Nuxt security screen both connect to it with no credential and
|
|
64
|
+
would be cut off the moment it were tightened. Every update is emitted to both, so
|
|
65
|
+
the two feeds can never disagree, and both namespaces share one connection handler,
|
|
66
|
+
so a client on the authenticated feed still starts the poll and still gets an
|
|
67
|
+
immediate snapshot.
|
|
68
|
+
|
|
69
|
+
A live session is the whole check, deliberately. Scoping the feed to the caller's
|
|
70
|
+
own sites is not possible today: manpower lives in HRM Labs' vendor id space, none
|
|
71
|
+
of those site ids match ours, and no field links the two — a site check would empty
|
|
72
|
+
the screen for the one customer using it. That mapping is a schema change and
|
|
73
|
+
belongs to the leads.
|
|
74
|
+
|
|
75
|
+
### Patch Changes
|
|
76
|
+
|
|
77
|
+
- 87c8679: Module gate: the kill switch now stops the 409, and the check stops reading when there is nothing to decide
|
|
78
|
+
|
|
79
|
+
Two follow-ups from the module-gate server review, both behaviour-neutral for
|
|
80
|
+
anybody who is not using the kill switch.
|
|
81
|
+
|
|
82
|
+
**`MODULE_LIST_GATE=off` now means off.** Every other part of the gate checked the
|
|
83
|
+
master switch; `mustAcknowledge` did not. So with the gate switched off, a save that
|
|
84
|
+
narrowed a client's module list was still refused with a 409 "acknowledge the impact
|
|
85
|
+
first" — the one lever a lead would reach for in an emergency, not working for the
|
|
86
|
+
one path that blocks a save from going through. Both the organisation and the site
|
|
87
|
+
save paths go through that function, so both are fixed. With the switch at its
|
|
88
|
+
default the 409 behaves exactly as before, and that is asserted.
|
|
89
|
+
|
|
90
|
+
**`moduleDeniedForCaller` no longer reads memberships when no list is enforced.** It
|
|
91
|
+
runs on every governed request and read the caller's memberships before finding out
|
|
92
|
+
whether there was anything to decide — and `members.user` has no index to use. It now
|
|
93
|
+
returns early unless the site or its organisation has an enforced list, which is what
|
|
94
|
+
the notification filter already did. No verdict changes: a client that really has an
|
|
95
|
+
enforced list is still measured exactly as before, and that is asserted too.
|
|
96
|
+
|
|
97
|
+
Also corrects the 3.65.0 changelog, which claimed `MODULE_LIST_GATE` switched all of
|
|
98
|
+
the gate off at once. It did not, for the reason above.
|
|
99
|
+
|
|
100
|
+
## 3.67.0
|
|
101
|
+
|
|
102
|
+
### Minor Changes
|
|
103
|
+
|
|
104
|
+
- 7b9ea2f: Notifications: stop sending alerts for modules a client was never given
|
|
105
|
+
|
|
106
|
+
`NOTIFY_ACCESS_FILTER` now defaults to `on` instead of `log`, so the module-based
|
|
107
|
+
drop is real: a recipient no longer gets a notification when every membership they
|
|
108
|
+
hold at the site denies every module the notification's category is about.
|
|
109
|
+
|
|
110
|
+
Only the module drop acts. The role-based check is still computed and logged and
|
|
111
|
+
never drops anybody, because most apps do not enforce their role gates yet and a
|
|
112
|
+
role-based drop would hide alerts for screens people can still open.
|
|
113
|
+
|
|
114
|
+
Unchanged: residents, anyone with no membership at the site, Seven365 staff, sends
|
|
115
|
+
with no site, and categories the catalogue does not govern are all exempt; any
|
|
116
|
+
error sends to everyone; and `MODULE_LIST_GATE=off` still disables it entirely.
|
|
117
|
+
`NOTIFY_ACCESS_FILTER=log` or `off` overrides this default with no deploy.
|
|
118
|
+
|
|
119
|
+
This is inert until a client's module list is enforced — measured read-only on
|
|
120
|
+
staging at the time of the flip, no organisation (0 of 199) and no site (0 of 256)
|
|
121
|
+
had a stored list and there were no acknowledged-save markers, so nothing is
|
|
122
|
+
dropped for anybody until a Super Admin saves a module list with the acknowledged
|
|
123
|
+
preview.
|
|
124
|
+
|
|
125
|
+
## 3.66.0
|
|
126
|
+
|
|
127
|
+
### Minor Changes
|
|
128
|
+
|
|
129
|
+
- b7f6302: Add a staff-only handler that repairs an organisation's missing owner membership.
|
|
130
|
+
|
|
131
|
+
An organisation created before 3.60.0 can exist with no `members` row at all, so
|
|
132
|
+
`GET /api/members/user/:id/app/organization` answers 404 and every console
|
|
133
|
+
landing page tells the real owner that no organisation exists. The new
|
|
134
|
+
`orgOwnerRepairHandlers` writes the one membership the onboarding path already
|
|
135
|
+
writes, for one organisation at a time, and only when that organisation is
|
|
136
|
+
active, holds exactly zero `organization` memberships, and has an account
|
|
137
|
+
registered under its own e-mail address. Staff-only (`organizations` console
|
|
138
|
+
permission), idempotent under a one-writer claim, audited, and behind the
|
|
139
|
+
`ORG_OWNER_REPAIR` switch. No schema change and no migration.
|
|
140
|
+
|
|
141
|
+
## 3.65.2
|
|
142
|
+
|
|
143
|
+
### Patch Changes
|
|
144
|
+
|
|
145
|
+
- fcd2f1e: `GET /api/members/users/:id` no longer shows anybody's memberships to any signed-in account. The person and Seven365 staff still get the full list; anyone else gets only the memberships in organisations they belong to, were invited to or own (an empty list, not an error, when there are none).
|
|
146
|
+
|
|
147
|
+
## 3.65.1
|
|
148
|
+
|
|
149
|
+
### Patch Changes
|
|
150
|
+
|
|
151
|
+
- 69714b4: Role writes: a site's own module list narrows a role only when the site belongs to the role's organisation. A service provider's role at a client's site is no longer refused modules the client switched off for that site — matching what the role editor now offers.
|
|
152
|
+
|
|
153
|
+
## 3.65.0
|
|
154
|
+
|
|
155
|
+
### Minor Changes
|
|
156
|
+
|
|
157
|
+
- c4dc50b: Module gate, server step: the deny-list endpoint, the impact preview, and
|
|
158
|
+
acknowledge-before-save. Everything ships inert and fails open.
|
|
159
|
+
|
|
160
|
+
- `useMemberController().getModulesByUserIdType` (for
|
|
161
|
+
`GET /api/members/user/:id/app/:type/modules?org=&site=`) answers
|
|
162
|
+
`{ denied: string[] }` for the membership `getByUserIdType` answers with. It
|
|
163
|
+
is the same self-or-staff guard. It answers `[]` for no list, an empty list,
|
|
164
|
+
a resident, Seven365 staff, a site of another organisation, any lookup
|
|
165
|
+
error, and `MODULE_LIST_GATE=off`. `ALWAYS_ALLOWED` is never denied.
|
|
166
|
+
- A saved list is enforced only once it has been saved through the
|
|
167
|
+
acknowledged preview. The marker is the save's own append-only console-audit
|
|
168
|
+
row (`gateListHash`). A list saved earlier, or changed any other way, behaves
|
|
169
|
+
as absent. No field is added to any organisation or site.
|
|
170
|
+
- `useOrgController().previewOrgModules` and
|
|
171
|
+
`useSiteController().previewSiteModules` (for
|
|
172
|
+
`POST /api/organizations/:id/modules/preview` and
|
|
173
|
+
`POST /api/sites/:id/modules/preview`) return who would lose what. They are
|
|
174
|
+
read-only and never go through `GET /api/roles`.
|
|
175
|
+
- `updateModules` and `updateSiteModules` accept `acknowledgeImpact`. A save
|
|
176
|
+
that takes a module away from somebody is refused with 409 until it is
|
|
177
|
+
acknowledged. An empty list restores everything and never needs it. Site
|
|
178
|
+
saves are now recorded in the console audit (`site.modules-changed`).
|
|
179
|
+
- `filterByAccess` (Q7) runs at the top of the notification `send()`. It is
|
|
180
|
+
`NOTIFY_ACCESS_FILTER=log` by default: it logs who would be filtered and
|
|
181
|
+
still sends to everyone. It is exported so API-core's own sender can call it.
|
|
182
|
+
- `moduleDeniedForCaller` (Q3) is the server-refusal primitive. It is
|
|
183
|
+
`MODULE_GATE_MODE=log` by default and never refuses. `enforce` refuses only
|
|
184
|
+
the keys in `MODULE_GATE_ENFORCE_KEYS`. Work stamped (`at`) before the
|
|
185
|
+
acknowledged save is accepted.
|
|
186
|
+
- `MODULE_LIST_GATE` (code default `on`) switches all of the above off at
|
|
187
|
+
once. CORRECTION (3.68.0): it did not. `mustAcknowledge` never read it, so
|
|
188
|
+
with the gate off a narrowing save was still refused with a 409. Fixed in
|
|
189
|
+
3.68.0; every other path did check it.
|
|
190
|
+
|
|
191
|
+
### Patch Changes
|
|
192
|
+
|
|
193
|
+
- c993ee4: POST /api/members/direct refuses (400) a role that belongs to a different organisation, unless the caller already holds that role in the organisation being joined.
|
|
194
|
+
- 74f228f: POST /api/members/direct: adding yourself now needs a role you may give yourself - Seven365 staff, the organisation's owner, a role you already hold there, or the role your own invitation offers. Enrolling somebody else is unchanged.
|
|
195
|
+
- ae42c1c: GET /api/organizations/id/:id returns the whole organisation record only to a caller with a relationship to it (member, invitee, owner, Seven365 staff, an active resident of one of its sites, or an engaged service provider). Everyone else gets the name-only record the anonymous lookup already returns. It never answers 401/403.
|
|
196
|
+
- 7363b8d: Site Settings saves are no longer refused because the client has one resident-app
|
|
197
|
+
switch turned off. A save is refused only when it would turn ON a resident-app
|
|
198
|
+
switch that the site has stored as off and the client has switched off.
|
|
199
|
+
- 9d1a0f0: PATCH /api/users/field/:id (and v2): on your own account you may change only name, contact, nric, dateOfBirth, profile and gender, and defaultOrg to an organisation you reach. status, email and plateNumber are staff-only.
|
|
200
|
+
|
|
201
|
+
## 3.64.5
|
|
202
|
+
|
|
203
|
+
### Patch Changes
|
|
204
|
+
|
|
205
|
+
- 49e1aef: A person's role now follows the site they are on.
|
|
206
|
+
|
|
207
|
+
`GET /api/members/user/:id/app/:type` accepts an optional `?site=` (a 24-hex
|
|
208
|
+
site id, like `?org=`). When it is sent, the answer is the person's live
|
|
209
|
+
membership of that app type pinned to that site (inside `?org=` when it is also
|
|
210
|
+
sent); failing that, their organisation-wide membership in `?org=`; failing
|
|
211
|
+
that, any live membership in `?org=`. When none of these exists the route
|
|
212
|
+
answers exactly as before. A removed membership never wins, and a site never
|
|
213
|
+
turns a found membership into "not found". Callers that do not send `site`
|
|
214
|
+
see no change. Login, auth-v2 and verification are unchanged.
|
|
215
|
+
|
|
216
|
+
The rule is the pure `pickSiteMembership` in `utils/member-lookup.util.ts`.
|
|
217
|
+
|
|
3
218
|
## 3.64.4
|
|
4
219
|
|
|
5
220
|
### Patch Changes
|
package/package.json
CHANGED