@nauticana/sail 1.1.33 → 1.1.34
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/README.md +17 -11
- package/package.json +1 -1
- package/src/agent/component/approval_inbox.html +63 -0
- package/src/agent/component/approval_inbox.ts +91 -0
- package/src/agent/component/decision_timeline.html +4 -4
- package/src/agent/component/decision_timeline.ts +2 -0
- package/src/agent/component/prompt_section_editor.html +4 -3
- package/src/agent/component/prompt_section_editor.ts +12 -5
- package/src/agent/component/release_sections.html +1 -1
- package/src/agent/component/release_sections.ts +2 -1
- package/src/agent/component/studio_page.html +269 -0
- package/src/agent/component/studio_page.ts +346 -0
- package/src/agent/component/studio_tab.ts +14 -0
- package/src/agent/component/turn_event_list.html +9 -0
- package/src/agent/index.ts +6 -0
- package/src/agent/model/agent_studio.ts +122 -9
- package/src/agent/model/approval.ts +42 -0
- package/src/agent/model/conversation.ts +9 -1
- package/src/agent/model/decision.ts +2 -1
- package/src/agent/model/turn_event.ts +10 -0
- package/src/agent/service/agent_studio.service.ts +36 -1
- package/src/agent/service/approval.service.ts +18 -0
- package/src/agent/util/release_diff.ts +33 -0
- package/src/agent/util/studio_errors.ts +11 -0
- package/src/agent/util/turn_timeline.ts +7 -1
- package/src/component/login/account_deletion.html +17 -4
- package/src/component/login/account_deletion.ts +35 -28
- package/src/component/login/social_login.ts +6 -5
- package/src/index.ts +1 -0
- package/src/model/auth.ts +17 -2
- package/src/service/auth.service.ts +10 -4
- package/src/service/caption_pipe.ts +26 -0
- package/src/service/label.service.ts +5 -4
- package/src/service/rest_url.ts +1 -0
package/src/model/auth.ts
CHANGED
|
@@ -115,11 +115,19 @@ export interface UserProfile {
|
|
|
115
115
|
|
|
116
116
|
// ── Re-authentication credentials ──
|
|
117
117
|
// Required by Setup2FA, Disable2FA, DeleteAccount, LogoutEverywhere — server
|
|
118
|
-
// rejects with 401
|
|
119
|
-
// Disable2FA additionally requires the current TOTP `code
|
|
118
|
+
// rejects with 401 unless one is supplied. `reauthCode` comes from
|
|
119
|
+
// sendReauthCode(). Disable2FA additionally requires the current TOTP `code`.
|
|
120
120
|
export interface ReauthCredentials {
|
|
121
121
|
password?: string;
|
|
122
122
|
twoFactorCode?: string;
|
|
123
|
+
reauthCode?: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export type ReauthChannel = 'email' | 'phone';
|
|
127
|
+
|
|
128
|
+
export interface ReauthSendResponse {
|
|
129
|
+
channel: ReauthChannel;
|
|
130
|
+
resendCountdownSec: number;
|
|
123
131
|
}
|
|
124
132
|
|
|
125
133
|
// ── Social login (ID token flow) ──
|
|
@@ -144,6 +152,13 @@ export interface LoginResponseSocial {
|
|
|
144
152
|
isNewUser: boolean;
|
|
145
153
|
singleDeviceSession?: boolean;
|
|
146
154
|
previousDeviceRevoked?: boolean;
|
|
155
|
+
// Client-side: the name Apple returns only on first authorization, never in the ID token.
|
|
156
|
+
socialName?: SocialName;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface SocialName {
|
|
160
|
+
firstName?: string;
|
|
161
|
+
lastName?: string;
|
|
147
162
|
}
|
|
148
163
|
|
|
149
164
|
// ── Push notification tokens ──
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
LoginResponseSocial,
|
|
8
8
|
OtpRequest, OtpResendRequest, OtpResponse, OtpVerifyRequest, OtpVerifyResponse,
|
|
9
9
|
PushPlatform, PushRegisterRequest,
|
|
10
|
-
ReauthCredentials,
|
|
10
|
+
ReauthChannel, ReauthCredentials, ReauthSendResponse,
|
|
11
11
|
SignupConsent, SocialLoginRequest, SocialProvider,
|
|
12
12
|
UserProfile,
|
|
13
13
|
} from '../model/auth';
|
|
@@ -112,6 +112,7 @@ export abstract class BaseAuthService extends BaseRestService {
|
|
|
112
112
|
protected get loginSocialUrl() { return this.url(RestURL.loginSocialURL); }
|
|
113
113
|
protected get logoutEverywhereUrl() { return this.url(RestURL.logoutEverywhereURL); }
|
|
114
114
|
protected get deleteAccountUrl() { return this.url(RestURL.deleteAccountURL); }
|
|
115
|
+
protected get reauthSendUrl() { return this.url(RestURL.reauthSendURL); }
|
|
115
116
|
protected get pushRegisterUrl() { return this.url(RestURL.pushRegisterURL); }
|
|
116
117
|
protected get pushRevokeUrl() { return this.url(RestURL.pushRevokeURL); }
|
|
117
118
|
protected get profileUrl() { return this.url(RestURL.profileURL); }
|
|
@@ -625,9 +626,14 @@ export abstract class BaseAuthService extends BaseRestService {
|
|
|
625
626
|
|
|
626
627
|
// ── Account lifecycle ──
|
|
627
628
|
|
|
629
|
+
/** Send a one-time code for ReauthCredentials.reauthCode; no channel prefers email. */
|
|
630
|
+
sendReauthCode(channel?: ReauthChannel): Observable<ReauthSendResponse> {
|
|
631
|
+
return this.http.post<ReauthSendResponse>(this.reauthSendUrl, { channel });
|
|
632
|
+
}
|
|
633
|
+
|
|
628
634
|
/**
|
|
629
635
|
* Soft-delete the caller's account. Requires recent re-authentication —
|
|
630
|
-
* pass
|
|
636
|
+
* pass `password`, `twoFactorCode` or `reauthCode`. Server anonymizes
|
|
631
637
|
* user_account, revokes all tokens / trusted devices / social links.
|
|
632
638
|
* Clears local session on success.
|
|
633
639
|
*/
|
|
@@ -640,8 +646,8 @@ export abstract class BaseAuthService extends BaseRestService {
|
|
|
640
646
|
|
|
641
647
|
/**
|
|
642
648
|
* Revoke every active refresh token for this user (sign out everywhere).
|
|
643
|
-
* Requires recent re-authentication — pass
|
|
644
|
-
* `
|
|
649
|
+
* Requires recent re-authentication — pass `password`, `twoFactorCode`
|
|
650
|
+
* or `reauthCode`.
|
|
645
651
|
*/
|
|
646
652
|
logoutEverywhere(reauth: ReauthCredentials): Observable<void> {
|
|
647
653
|
return this.http.post<void>(this.logoutEverywhereUrl, reauth);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DestroyRef, Pipe, PipeTransform, inject, signal } from '@angular/core';
|
|
2
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
|
+
import { LabelService } from './label.service';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `{{ code | sailCaption:'constant_id' }}` — the backend caption of a constant code, the code
|
|
7
|
+
* itself until its domain loads or when the domain lacks it. Impure so it re-renders on load.
|
|
8
|
+
*/
|
|
9
|
+
@Pipe({ name: 'sailCaption', pure: false })
|
|
10
|
+
export class CaptionPipe implements PipeTransform {
|
|
11
|
+
private readonly labels = inject(LabelService);
|
|
12
|
+
private readonly destroyRef = inject(DestroyRef);
|
|
13
|
+
private readonly requested = new Set<string>();
|
|
14
|
+
private readonly loaded = signal(0);
|
|
15
|
+
|
|
16
|
+
transform(code: string | null | undefined, constantId: string): string {
|
|
17
|
+
if (!code) return '';
|
|
18
|
+
this.loaded();
|
|
19
|
+
if (!this.requested.has(constantId)) {
|
|
20
|
+
this.requested.add(constantId);
|
|
21
|
+
this.labels.loadLabels(constantId).pipe(takeUntilDestroyed(this.destroyRef))
|
|
22
|
+
.subscribe({ next: () => this.loaded.update((n) => n + 1), error: () => this.requested.delete(constantId) });
|
|
23
|
+
}
|
|
24
|
+
return this.labels.getLabel(constantId, code);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -36,9 +36,10 @@ export class LabelService {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* Load one
|
|
40
|
-
*
|
|
41
|
-
*
|
|
39
|
+
* Load one caption map from ApplicationData: a `constant_value` domain by its
|
|
40
|
+
* constant id, or a catalog table registered in `foreign_key_lookup` by its
|
|
41
|
+
* table name. Completed and concurrent requests are cached; a failed
|
|
42
|
+
* application-data load is evicted so a later call can retry.
|
|
42
43
|
*/
|
|
43
44
|
loadLabels(constantId: string): Observable<void> {
|
|
44
45
|
const domain = constantId.trim();
|
|
@@ -53,7 +54,7 @@ export class LabelService {
|
|
|
53
54
|
tap({
|
|
54
55
|
next: (data) => this.labels.set(
|
|
55
56
|
domain,
|
|
56
|
-
new Map(Object.entries(data.ConstantCache?.[domain] ?? {})),
|
|
57
|
+
new Map(Object.entries(data.ConstantCache?.[domain] ?? data.TableCache?.[domain] ?? {})),
|
|
57
58
|
),
|
|
58
59
|
error: () => this.pendingLoads.delete(domain),
|
|
59
60
|
}),
|
package/src/service/rest_url.ts
CHANGED
|
@@ -45,6 +45,7 @@ export const RestURL = {
|
|
|
45
45
|
ssoSamlMetadataURL: '/public/sso/saml/metadata',
|
|
46
46
|
logoutEverywhereURL: '/api/user/logout-everywhere',
|
|
47
47
|
deleteAccountURL: '/api/user/account',
|
|
48
|
+
reauthSendURL: '/api/user/reauth/send',
|
|
48
49
|
// Self-service profile (keel ProfileHandler). GET profileURL reads the
|
|
49
50
|
// current profile; POST updates name/locale. Email/phone are verify-before-
|
|
50
51
|
// apply (request → confirm). A consumer whose backend mounts these under a
|