@orechio/platform-angular 0.2.0 → 0.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.
Files changed (21) hide show
  1. package/README.md +64 -64
  2. package/fesm2022/orechio-platform-angular-account-account-client-mPl0tzMg.mjs +56 -0
  3. package/fesm2022/orechio-platform-angular-account-account-client-mPl0tzMg.mjs.map +1 -0
  4. package/fesm2022/orechio-platform-angular-account-forgot-password.page-5_8R5B4m.mjs +136 -0
  5. package/fesm2022/orechio-platform-angular-account-forgot-password.page-5_8R5B4m.mjs.map +1 -0
  6. package/fesm2022/orechio-platform-angular-account-initial-branch.page-Cmy07JGF.mjs +121 -0
  7. package/fesm2022/orechio-platform-angular-account-initial-branch.page-Cmy07JGF.mjs.map +1 -0
  8. package/fesm2022/orechio-platform-angular-account-resend-verification.page-qckKAlPk.mjs +122 -0
  9. package/fesm2022/orechio-platform-angular-account-resend-verification.page-qckKAlPk.mjs.map +1 -0
  10. package/fesm2022/orechio-platform-angular-account-token-password.page-AHqb8mFk.mjs +181 -0
  11. package/fesm2022/orechio-platform-angular-account-token-password.page-AHqb8mFk.mjs.map +1 -0
  12. package/fesm2022/orechio-platform-angular-account-verify-email.page-CHs0EwDf.mjs +121 -0
  13. package/fesm2022/orechio-platform-angular-account-verify-email.page-CHs0EwDf.mjs.map +1 -0
  14. package/fesm2022/orechio-platform-angular-account.mjs +106 -0
  15. package/fesm2022/orechio-platform-angular-account.mjs.map +1 -0
  16. package/fesm2022/orechio-platform-angular.mjs +224 -3
  17. package/fesm2022/orechio-platform-angular.mjs.map +1 -1
  18. package/package.json +5 -11
  19. package/types/orechio-platform-angular-account.d.ts +97 -0
  20. package/types/orechio-platform-angular.d.ts +120 -2
  21. package/LICENSE +0 -21
@@ -13,6 +13,12 @@ interface PlatformAngularAuthPaths {
13
13
  refresh: string;
14
14
  logout: string;
15
15
  me?: string;
16
+ /**
17
+ * Branch switch for an already-authenticated session. Optional: only BFFs that
18
+ * expose an authenticated switch endpoint set it, and `AuthClient.selectBranch`
19
+ * fails fast when it is absent rather than guessing a URL.
20
+ */
21
+ selectBranch?: string;
16
22
  /**
17
23
  * Unwraps the raw auth-endpoint response body into TUser. Defaults to the
18
24
  * identity function (response body IS the user object), matching Store's
@@ -109,6 +115,21 @@ declare class AuthClient<TUser extends SessionUser = SessionUser> {
109
115
  * which has no dedicated session-read endpoint and bootstraps via refresh).
110
116
  */
111
117
  initSession(): Observable<TUser>;
118
+ /**
119
+ * Asks the BFF to make `branchId` the current branch of the session that is
120
+ * already authenticated. No credentials are involved and none are re-sent: the
121
+ * browser proves nothing here beyond the session it already holds.
122
+ *
123
+ * `branchId` is a **requested target, never an authorization**. The BFF forwards
124
+ * it to the Platform, which re-reads the user's grants and refuses what is not
125
+ * granted — a rejection arrives as a failed request, and the session store is
126
+ * left exactly as it was, still on the previous branch.
127
+ *
128
+ * The store is updated only from the session the server returns, never
129
+ * optimistically from the requested id: the whole point of an explicit switch is
130
+ * that the server, not the client, decides which branch the user ends up in.
131
+ */
132
+ selectBranch(branchId: string): Observable<TUser>;
112
133
  refresh(): Observable<TUser>;
113
134
  /**
114
135
  * Clears the local session unconditionally — on success, on error, and on
@@ -123,6 +144,103 @@ declare class AuthClient<TUser extends SessionUser = SessionUser> {
123
144
  static ɵprov: i0.ɵɵInjectableDeclaration<AuthClient<any>>;
124
145
  }
125
146
 
147
+ /**
148
+ * Control-flow code the Platform's auth contract returns (HTTP 409) when the
149
+ * authenticated user has access to more than one branch and none was chosen.
150
+ *
151
+ * It is deliberately NOT a failure: no session is created, no cookie is set,
152
+ * and the caller is expected to ask the user which branch to enter. Treating
153
+ * it as a generic error is the bug this constant exists to prevent.
154
+ */
155
+ declare const BRANCH_SELECTION_REQUIRED_CODE = "auth.branch_selection_required";
156
+ /**
157
+ * One selectable branch.
158
+ *
159
+ * `name` is optional because the current backend contract carries branch ids
160
+ * only — see `readBranchSelectionRequired`. Modelling it as optional now means
161
+ * the day the backend starts sending names, consumers get them without a
162
+ * breaking change to this type.
163
+ */
164
+ interface BranchOption {
165
+ readonly id: string;
166
+ readonly name?: string | null;
167
+ }
168
+ /** Payload of a branch-selection-required response, normalized. */
169
+ interface BranchSelectionRequired {
170
+ readonly branches: readonly BranchOption[];
171
+ }
172
+ /**
173
+ * Recognizes a branch-selection-required response and normalizes its payload,
174
+ * or returns `null` for anything else — so callers branch on a value instead of
175
+ * re-deriving the contract from status codes and body shapes.
176
+ *
177
+ * Reads three wire shapes, in this order of preference:
178
+ *
179
+ * 1. `branchOptions: [{ id, name }]` — the display metadata the Platform sends
180
+ * alongside the ids. Preferred when present, because it is the only shape
181
+ * that lets an operator tell the branches apart.
182
+ * 2. `branches: ["<guid>"]` — the original contract. Still authoritative for
183
+ * selection, and still enough on its own.
184
+ * 3. `branches: [{ id, name }]` — tolerated since 0.3.0.
185
+ *
186
+ * Reading all three is what makes the rollout order irrelevant: a frontend on
187
+ * this version works against a backend that has the metadata and against one
188
+ * that does not, and neither side has to ship first.
189
+ *
190
+ * Entries without a usable id are dropped rather than rendered as blanks: an
191
+ * unselectable option in a selection list is worse than a shorter list.
192
+ */
193
+ declare function readBranchSelectionRequired(error: unknown): BranchSelectionRequired | null;
194
+
195
+ /**
196
+ * Explicit branch picker for the multi-branch login step.
197
+ *
198
+ * Deliberately narrow: it receives options, renders them, and emits the id the
199
+ * user actually chose. It does not call any backend, hold credentials, read
200
+ * tokens, touch storage, or know which product it is rendering inside — the
201
+ * flow around it belongs to the consumer, and the copy around it belongs to the
202
+ * consumer's login page.
203
+ *
204
+ * **It never picks for the user.** When the backend answers
205
+ * `auth.branch_selection_required` it has already refused to choose (no session
206
+ * is created); a selector that quietly defaulted to the first option would put
207
+ * the arbitrary choice back one layer up, in the place hardest to notice.
208
+ *
209
+ * Rendered as a radio group so the browser gives keyboard navigation, focus
210
+ * management, and screen-reader semantics for free — a list of buttons would
211
+ * need all three re-implemented, worse.
212
+ */
213
+ declare class BranchSelector {
214
+ /** Options to choose from. An empty list renders the empty state, never a silent no-op. */
215
+ readonly branches: i0.InputSignal<readonly BranchOption[]>;
216
+ /** Blocks input while the consumer is completing the sign-in round-trip. */
217
+ readonly busy: i0.InputSignal<boolean>;
218
+ readonly legend: i0.InputSignal<string>;
219
+ readonly confirmLabel: i0.InputSignal<string>;
220
+ readonly emptyLabel: i0.InputSignal<string>;
221
+ /** Emits only in response to a user action. */
222
+ readonly selected: i0.OutputEmitterRef<string>;
223
+ protected chosen: string | null;
224
+ protected choose(id: string): void;
225
+ protected confirm(): void;
226
+ /**
227
+ * The name is the label whenever the contract carries one. The id fragment stays
228
+ * as secondary text rather than disappearing: the domain allows two branches to
229
+ * share a name, and when that happens the fragment is the only thing telling
230
+ * them apart.
231
+ *
232
+ * Without a name — an older backend, or metadata the server could not compose —
233
+ * the positional fallback keeps the list selectable. Two raw identifiers side by
234
+ * side are technically a choice and practically a coin flip, which is exactly
235
+ * why the name is preferred whenever it exists.
236
+ */
237
+ protected label(branch: BranchOption, index: number): string;
238
+ /** Fragment of the id, shown beside the label to disambiguate repeated names. */
239
+ protected fragment(branch: BranchOption): string;
240
+ static ɵfac: i0.ɵɵFactoryDeclaration<BranchSelector, never>;
241
+ static ɵcmp: i0.ɵɵComponentDeclaration<BranchSelector, "orechio-branch-selector", never, { "branches": { "alias": "branches"; "required": true; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "legend": { "alias": "legend"; "required": false; "isSignal": true; }; "confirmLabel": { "alias": "confirmLabel"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; }, { "selected": "selected"; }, never, never, true, never>;
242
+ }
243
+
126
244
  /**
127
245
  * Forces `withCredentials: true` on same-origin API requests, so the BFF's
128
246
  * HttpOnly session cookie is sent. Proven identically in both consumers.
@@ -271,5 +389,5 @@ interface PagedResult<T> {
271
389
  hasPrevious: boolean;
272
390
  }
273
391
 
274
- export { AuthClient, CapabilityDirective, PLATFORM_ANGULAR_CONFIG, SessionStore, credentialsInterceptor, hasCapability, normalizeProblemDetails, providePlatformAngularConfig, providePlatformAngularHttp, sessionExpiryInterceptor };
275
- export type { CapabilityMap, PagedResult, PlatformAngularAuthPaths, PlatformAngularConfig, ProblemDetails, SessionUser };
392
+ export { AuthClient, BRANCH_SELECTION_REQUIRED_CODE, BranchSelector, CapabilityDirective, PLATFORM_ANGULAR_CONFIG, SessionStore, credentialsInterceptor, hasCapability, normalizeProblemDetails, providePlatformAngularConfig, providePlatformAngularHttp, readBranchSelectionRequired, sessionExpiryInterceptor };
393
+ export type { BranchOption, BranchSelectionRequired, CapabilityMap, PagedResult, PlatformAngularAuthPaths, PlatformAngularConfig, ProblemDetails, SessionUser };
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Orechio
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.