@vertesia/ui 1.6.0-dev.20261008.064737Z → 1.6.0-dev.20261014.015055Z
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 +24 -0
- package/lib/boot/index.d.ts +12 -1
- package/lib/boot/index.d.ts.map +1 -1
- package/lib/boot/index.js +65 -10
- package/lib/boot/index.js.map +1 -1
- package/lib/boot/text.d.ts +13 -0
- package/lib/boot/text.d.ts.map +1 -0
- package/lib/boot/text.js +68 -0
- package/lib/boot/text.js.map +1 -0
- package/lib/core/components/shadcn/button.d.ts +1 -0
- package/lib/core/components/shadcn/button.d.ts.map +1 -1
- package/lib/core/components/shadcn/button.js +2 -2
- package/lib/core/components/shadcn/button.js.map +1 -1
- package/lib/core/components/shadcn/selectBox.d.ts.map +1 -1
- package/lib/core/components/shadcn/selectBox.js +2 -2
- package/lib/core/components/shadcn/selectBox.js.map +1 -1
- package/lib/env/index.d.ts +1 -1
- package/lib/env/index.d.ts.map +1 -1
- package/lib/env/index.js +1 -1
- package/lib/env/index.js.map +1 -1
- package/lib/features/agent/PayloadBuilder.d.ts +6 -0
- package/lib/features/agent/PayloadBuilder.d.ts.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.d.ts.map +1 -1
- package/lib/features/agent/chat/AskUserWidget.js +2 -1
- package/lib/features/agent/chat/AskUserWidget.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +6 -4
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +2 -253
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts +1 -3
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js +2 -8
- package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js +58 -0
- package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.d.ts +4 -0
- package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.d.ts.map +1 -0
- package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.js +248 -0
- package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.js.map +1 -0
- package/lib/features/agent/chat/SkillWidgetProvider.d.ts.map +1 -1
- package/lib/features/agent/chat/SkillWidgetProvider.js +3 -2
- package/lib/features/agent/chat/SkillWidgetProvider.js.map +1 -1
- package/lib/i18n/LanguageProvider.d.ts +9 -1
- package/lib/i18n/LanguageProvider.d.ts.map +1 -1
- package/lib/i18n/LanguageProvider.js +7 -4
- package/lib/i18n/LanguageProvider.js.map +1 -1
- package/lib/i18n/locales/ar.json +6 -1
- package/lib/i18n/locales/de.json +6 -1
- package/lib/i18n/locales/en.json +6 -1
- package/lib/i18n/locales/es.json +6 -1
- package/lib/i18n/locales/fr.json +6 -1
- package/lib/i18n/locales/it.json +6 -1
- package/lib/i18n/locales/ja.json +6 -1
- package/lib/i18n/locales/ko.json +6 -1
- package/lib/i18n/locales/pt.json +6 -1
- package/lib/i18n/locales/ru.json +6 -1
- package/lib/i18n/locales/tr.json +6 -1
- package/lib/i18n/locales/zh-TW.json +6 -1
- package/lib/i18n/locales/zh.json +6 -1
- package/lib/i18n/rtl.d.ts +4 -2
- package/lib/i18n/rtl.d.ts.map +1 -1
- package/lib/i18n/rtl.js +4 -2
- package/lib/i18n/rtl.js.map +1 -1
- package/lib/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/session/UserSessionProvider.js +10 -4
- package/lib/session/UserSessionProvider.js.map +1 -1
- package/lib/session/auth/composable.d.ts +1 -5
- package/lib/session/auth/composable.d.ts.map +1 -1
- package/lib/session/auth/composable.js +1 -10
- package/lib/session/auth/composable.js.map +1 -1
- package/lib/session/auth/firebase.d.ts.map +1 -1
- package/lib/session/auth/firebase.js +8 -5
- package/lib/session/auth/firebase.js.map +1 -1
- package/lib/session/auth/oauth.d.ts.map +1 -1
- package/lib/session/auth/oauth.js +53 -25
- package/lib/session/auth/oauth.js.map +1 -1
- package/lib/session/auth/vertesiaHosts.d.ts +0 -40
- package/lib/session/auth/vertesiaHosts.d.ts.map +1 -1
- package/lib/session/auth/vertesiaHosts.js +2 -45
- package/lib/session/auth/vertesiaHosts.js.map +1 -1
- package/lib/session/index.d.ts +1 -1
- package/lib/session/index.d.ts.map +1 -1
- package/lib/session/index.js +1 -1
- package/lib/session/index.js.map +1 -1
- package/lib/session/scopeSelection.d.ts +4 -0
- package/lib/session/scopeSelection.d.ts.map +1 -1
- package/lib/session/scopeSelection.js +11 -0
- package/lib/session/scopeSelection.js.map +1 -1
- package/lib/shell/VertesiaShell.d.ts +7 -2
- package/lib/shell/VertesiaShell.d.ts.map +1 -1
- package/lib/shell/VertesiaShell.js +2 -2
- package/lib/shell/VertesiaShell.js.map +1 -1
- package/lib/shell/login/InviteAcceptModal.d.ts.map +1 -1
- package/lib/shell/login/InviteAcceptModal.js +83 -42
- package/lib/shell/login/InviteAcceptModal.js.map +1 -1
- package/lib/vertesia-ui-boot.js +52 -15
- package/lib/vertesia-ui-boot.js.map +1 -1
- package/lib/vertesia-ui-core.js +44 -44
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-env.js +1 -1
- package/lib/vertesia-ui-env.js.map +1 -1
- package/lib/vertesia-ui-features.js +570 -585
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.B1Nd8-dE.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.B1Nd8-dE.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.B2Z7mx1x.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.B2Z7mx1x.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.B756-YtS.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.B756-YtS.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.BICdgAEn.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.BICdgAEn.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.B_yx0c2A.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.B_yx0c2A.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.BwPrGiQn.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.BwPrGiQn.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.CfQbOHm3.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.CfQbOHm3.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.DMISlF16.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.DMISlF16.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.D_WA36Yq.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.D_WA36Yq.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.Dp3KuMs-.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.Dp3KuMs-.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.DsioKoQ3.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.DsioKoQ3.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.QEIqEPlv.chunk.js +5 -0
- package/lib/vertesia-ui-i18n.QEIqEPlv.chunk.js.map +1 -0
- package/lib/vertesia-ui-i18n.js +2 -2
- package/lib/vertesia-ui-i18n.js.map +1 -1
- package/lib/vertesia-ui-layout.js +15 -15
- package/lib/vertesia-ui-layout.js.map +1 -1
- package/lib/vertesia-ui-rich-text.js +44 -44
- package/lib/vertesia-ui-rich-text.js.map +1 -1
- package/lib/vertesia-ui-session.js +1 -1
- package/lib/vertesia-ui-session.js.map +1 -1
- package/lib/vertesia-ui-shell.js +51 -51
- package/lib/vertesia-ui-shell.js.map +1 -1
- package/lib/vertesia-ui-widgets.js +51 -51
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/package.json +20 -20
- package/src/boot/index.ts +74 -11
- package/src/boot/text.ts +80 -0
- package/src/core/components/shadcn/button.tsx +3 -2
- package/src/core/components/shadcn/selectBox.tsx +12 -4
- package/src/css/index.css +1 -1
- package/src/css/typography.css +111 -88
- package/src/env/index.ts +0 -2
- package/src/features/agent/chat/AskUserWidget.tsx +3 -1
- package/src/features/agent/chat/ModernAgentConversation.tsx +7 -4
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +2 -253
- package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.tsx +2 -8
- package/src/features/agent/chat/ModernAgentOutput/SummaryConversation.ts +60 -0
- package/src/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.ts +248 -0
- package/src/features/agent/chat/SkillWidgetProvider.tsx +3 -2
- package/src/i18n/LanguageProvider.tsx +16 -4
- package/src/i18n/locales/ar.json +6 -1
- package/src/i18n/locales/de.json +6 -1
- package/src/i18n/locales/en.json +6 -1
- package/src/i18n/locales/es.json +6 -1
- package/src/i18n/locales/fr.json +6 -1
- package/src/i18n/locales/it.json +6 -1
- package/src/i18n/locales/ja.json +6 -1
- package/src/i18n/locales/ko.json +6 -1
- package/src/i18n/locales/pt.json +6 -1
- package/src/i18n/locales/ru.json +6 -1
- package/src/i18n/locales/tr.json +6 -1
- package/src/i18n/locales/zh-TW.json +6 -1
- package/src/i18n/locales/zh.json +6 -1
- package/src/i18n/rtl.ts +5 -2
- package/src/session/UserSessionProvider.tsx +11 -4
- package/src/session/auth/composable.ts +1 -11
- package/src/session/auth/firebase.ts +9 -6
- package/src/session/auth/oauth.ts +65 -25
- package/src/session/auth/vertesiaHosts.ts +2 -47
- package/src/session/index.ts +1 -1
- package/src/session/scopeSelection.ts +13 -0
- package/src/shell/VertesiaShell.tsx +8 -2
- package/src/shell/login/InviteAcceptModal.tsx +112 -65
- package/lib/vertesia-ui-i18n.B0orbJb6.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.B0orbJb6.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BChwIQVA.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BChwIQVA.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BTEcAVQm.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BTEcAVQm.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BeJQKbv7.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BeJQKbv7.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BpGr0-5g.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BpGr0-5g.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.Bs8x-1wI.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.Bs8x-1wI.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.BymQoOm0.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.BymQoOm0.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.CNT_wabV.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.CNT_wabV.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.Cxh1iVk0.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.Cxh1iVk0.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.DLYCM9fV.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.DLYCM9fV.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.QvAVguDs.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.QvAVguDs.chunk.js.map +0 -1
- package/lib/vertesia-ui-i18n.smozeSmI.chunk.js +0 -5
- package/lib/vertesia-ui-i18n.smozeSmI.chunk.js.map +0 -1
package/src/i18n/locales/ar.json
CHANGED
|
@@ -261,8 +261,9 @@
|
|
|
261
261
|
"agent.thinking": "جارٍ التفكير...",
|
|
262
262
|
"agent.timeout": "انتهت المهلة",
|
|
263
263
|
"agent.toggleRightSidebar": "تبديل الشريط الجانبي الأيمن",
|
|
264
|
+
"agent.typeDifferentResponse": "أو اكتب ردًا مختلفًا...",
|
|
264
265
|
"agent.typeYourMessage": "اكتب رسالتك...",
|
|
265
|
-
"agent.typeYourResponse": "اكتب
|
|
266
|
+
"agent.typeYourResponse": "أو اكتب ردًا مختلفًا...",
|
|
266
267
|
"agent.unableToOpenPrint": "تعذر فتح معاينة الطباعة",
|
|
267
268
|
"agent.unknownError": "خطأ غير معروف",
|
|
268
269
|
"agent.unknownTime": "وقت غير معروف",
|
|
@@ -390,6 +391,10 @@
|
|
|
390
391
|
"layout.searchPlaceholder": "بحث...",
|
|
391
392
|
"layout.toggleNavigationMenu": "تبديل قائمة التنقل",
|
|
392
393
|
"login.accept": "قبول",
|
|
394
|
+
"login.inviteActionFailed": "تعذّر تحديث هذه الدعوة. تم تحديث القائمة.",
|
|
395
|
+
"login.inviteRole": "الدور: {{role}}",
|
|
396
|
+
"login.invitedBy": "دعاك {{name}}",
|
|
397
|
+
"login.invitesIntro": "تمت دعوتك للانضمام إلى الحسابات التالية. اقبل كل دعوة أو ارفضها.",
|
|
393
398
|
"login.reject": "رفض",
|
|
394
399
|
"login.reviewInvites": "مراجعة الدعوات",
|
|
395
400
|
"login.terminal.account": "الحساب",
|
package/src/i18n/locales/de.json
CHANGED
|
@@ -249,8 +249,9 @@
|
|
|
249
249
|
"agent.thinking": "Denke nach...",
|
|
250
250
|
"agent.timeout": "Zeitüberschreitung",
|
|
251
251
|
"agent.toggleRightSidebar": "Rechte Seitenleiste umschalten",
|
|
252
|
+
"agent.typeDifferentResponse": "Oder geben Sie eine andere Antwort ein...",
|
|
252
253
|
"agent.typeYourMessage": "Geben Sie Ihre Nachricht ein...",
|
|
253
|
-
"agent.typeYourResponse": "
|
|
254
|
+
"agent.typeYourResponse": "Oder geben Sie eine andere Antwort ein...",
|
|
254
255
|
"agent.unableToOpenPrint": "Druckvorschau konnte nicht geöffnet werden",
|
|
255
256
|
"agent.unknownError": "Unbekannter Fehler",
|
|
256
257
|
"agent.unknownTime": "Unbekannte Zeit",
|
|
@@ -378,6 +379,10 @@
|
|
|
378
379
|
"layout.searchPlaceholder": "Suchen...",
|
|
379
380
|
"layout.toggleNavigationMenu": "Navigationsmenü umschalten",
|
|
380
381
|
"login.accept": "Akzeptieren",
|
|
382
|
+
"login.inviteActionFailed": "Diese Einladung konnte nicht aktualisiert werden. Die Liste wurde aktualisiert.",
|
|
383
|
+
"login.inviteRole": "Rolle: {{role}}",
|
|
384
|
+
"login.invitedBy": "Eingeladen von {{name}}",
|
|
385
|
+
"login.invitesIntro": "Sie wurden eingeladen, den folgenden Konten beizutreten. Nehmen Sie jede Einladung an oder lehnen Sie sie ab.",
|
|
381
386
|
"login.reject": "Ablehnen",
|
|
382
387
|
"login.reviewInvites": "Einladungen überprüfen",
|
|
383
388
|
"login.terminal.account": "Konto",
|
package/src/i18n/locales/en.json
CHANGED
|
@@ -322,8 +322,9 @@
|
|
|
322
322
|
"agent.thinking": "Thinking...",
|
|
323
323
|
"agent.timeout": "Timed out",
|
|
324
324
|
"agent.toggleRightSidebar": "Toggle right sidebar",
|
|
325
|
+
"agent.typeDifferentResponse": "Or type a different response...",
|
|
325
326
|
"agent.typeYourMessage": "Type your message...",
|
|
326
|
-
"agent.typeYourResponse": "
|
|
327
|
+
"agent.typeYourResponse": "Or type a different response...",
|
|
327
328
|
"agent.unableToOpenPrint": "Unable to open print preview",
|
|
328
329
|
"agent.unknownError": "Unknown error",
|
|
329
330
|
"agent.unknownTime": "Unknown time",
|
|
@@ -688,6 +689,10 @@
|
|
|
688
689
|
"layout.searchPlaceholder": "Search...",
|
|
689
690
|
"layout.toggleNavigationMenu": "Toggle navigation menu",
|
|
690
691
|
"login.accept": "Accept",
|
|
692
|
+
"login.inviteActionFailed": "This invite could not be updated. The list has been refreshed.",
|
|
693
|
+
"login.inviteRole": "Role: {{role}}",
|
|
694
|
+
"login.invitedBy": "Invited by {{name}}",
|
|
695
|
+
"login.invitesIntro": "You have been invited to join the following accounts. Accept or reject each invite.",
|
|
691
696
|
"login.reject": "Reject",
|
|
692
697
|
"login.reviewInvites": "Review Invites",
|
|
693
698
|
"login.terminal.account": "Account",
|
package/src/i18n/locales/es.json
CHANGED
|
@@ -251,8 +251,9 @@
|
|
|
251
251
|
"agent.thinking": "Pensando...",
|
|
252
252
|
"agent.timeout": "Tiempo agotado",
|
|
253
253
|
"agent.toggleRightSidebar": "Alternar panel lateral",
|
|
254
|
+
"agent.typeDifferentResponse": "O escribe una respuesta diferente...",
|
|
254
255
|
"agent.typeYourMessage": "Escribe tu mensaje...",
|
|
255
|
-
"agent.typeYourResponse": "
|
|
256
|
+
"agent.typeYourResponse": "O escribe una respuesta diferente...",
|
|
256
257
|
"agent.unableToOpenPrint": "No se pudo abrir la vista previa de impresión",
|
|
257
258
|
"agent.unknownError": "Error desconocido",
|
|
258
259
|
"agent.unknownTime": "Hora desconocida",
|
|
@@ -380,6 +381,10 @@
|
|
|
380
381
|
"layout.searchPlaceholder": "Buscar...",
|
|
381
382
|
"layout.toggleNavigationMenu": "Alternar menú de navegación",
|
|
382
383
|
"login.accept": "Aceptar",
|
|
384
|
+
"login.inviteActionFailed": "No se pudo actualizar esta invitación. La lista se ha actualizado.",
|
|
385
|
+
"login.inviteRole": "Rol: {{role}}",
|
|
386
|
+
"login.invitedBy": "Invitado por {{name}}",
|
|
387
|
+
"login.invitesIntro": "Ha sido invitado a unirse a las siguientes cuentas. Acepte o rechace cada invitación.",
|
|
383
388
|
"login.reject": "Rechazar",
|
|
384
389
|
"login.reviewInvites": "Revisar invitaciones",
|
|
385
390
|
"login.terminal.account": "Cuenta",
|
package/src/i18n/locales/fr.json
CHANGED
|
@@ -251,8 +251,9 @@
|
|
|
251
251
|
"agent.thinking": "Réflexion...",
|
|
252
252
|
"agent.timeout": "Délai dépassé",
|
|
253
253
|
"agent.toggleRightSidebar": "Basculer le panneau latéral",
|
|
254
|
+
"agent.typeDifferentResponse": "Ou saisissez une autre réponse...",
|
|
254
255
|
"agent.typeYourMessage": "Saisissez votre message...",
|
|
255
|
-
"agent.typeYourResponse": "
|
|
256
|
+
"agent.typeYourResponse": "Ou saisissez une autre réponse...",
|
|
256
257
|
"agent.unableToOpenPrint": "Impossible d'ouvrir l'aperçu d'impression",
|
|
257
258
|
"agent.unknownError": "Erreur inconnue",
|
|
258
259
|
"agent.unknownTime": "Heure inconnue",
|
|
@@ -380,6 +381,10 @@
|
|
|
380
381
|
"layout.searchPlaceholder": "Rechercher...",
|
|
381
382
|
"layout.toggleNavigationMenu": "Afficher ou masquer le menu de navigation",
|
|
382
383
|
"login.accept": "Accepter",
|
|
384
|
+
"login.inviteActionFailed": "Cette invitation n'a pas pu être mise à jour. La liste a été actualisée.",
|
|
385
|
+
"login.inviteRole": "Rôle : {{role}}",
|
|
386
|
+
"login.invitedBy": "Invité par {{name}}",
|
|
387
|
+
"login.invitesIntro": "Vous avez été invité à rejoindre les comptes suivants. Acceptez ou refusez chaque invitation.",
|
|
383
388
|
"login.reject": "Refuser",
|
|
384
389
|
"login.reviewInvites": "Examiner les invitations",
|
|
385
390
|
"login.terminal.account": "Compte",
|
package/src/i18n/locales/it.json
CHANGED
|
@@ -251,8 +251,9 @@
|
|
|
251
251
|
"agent.thinking": "Sto pensando...",
|
|
252
252
|
"agent.timeout": "Tempo scaduto",
|
|
253
253
|
"agent.toggleRightSidebar": "Alterna pannello laterale",
|
|
254
|
+
"agent.typeDifferentResponse": "Oppure scrivi una risposta diversa...",
|
|
254
255
|
"agent.typeYourMessage": "Scrivi il tuo messaggio...",
|
|
255
|
-
"agent.typeYourResponse": "
|
|
256
|
+
"agent.typeYourResponse": "Oppure scrivi una risposta diversa...",
|
|
256
257
|
"agent.unableToOpenPrint": "Impossibile aprire l'anteprima di stampa",
|
|
257
258
|
"agent.unknownError": "Errore sconosciuto",
|
|
258
259
|
"agent.unknownTime": "Ora sconosciuta",
|
|
@@ -380,6 +381,10 @@
|
|
|
380
381
|
"layout.searchPlaceholder": "Cerca...",
|
|
381
382
|
"layout.toggleNavigationMenu": "Attiva o disattiva il menu di navigazione",
|
|
382
383
|
"login.accept": "Accetta",
|
|
384
|
+
"login.inviteActionFailed": "Impossibile aggiornare questo invito. L'elenco è stato aggiornato.",
|
|
385
|
+
"login.inviteRole": "Ruolo: {{role}}",
|
|
386
|
+
"login.invitedBy": "Invitato da {{name}}",
|
|
387
|
+
"login.invitesIntro": "Sei stato invitato a unirti ai seguenti account. Accetta o rifiuta ogni invito.",
|
|
383
388
|
"login.reject": "Rifiuta",
|
|
384
389
|
"login.reviewInvites": "Rivedi inviti",
|
|
385
390
|
"login.terminal.account": "Account",
|
package/src/i18n/locales/ja.json
CHANGED
|
@@ -249,8 +249,9 @@
|
|
|
249
249
|
"agent.thinking": "考え中...",
|
|
250
250
|
"agent.timeout": "タイムアウト",
|
|
251
251
|
"agent.toggleRightSidebar": "右サイドバーの切り替え",
|
|
252
|
+
"agent.typeDifferentResponse": "または別の回答を入力...",
|
|
252
253
|
"agent.typeYourMessage": "メッセージを入力...",
|
|
253
|
-
"agent.typeYourResponse": "
|
|
254
|
+
"agent.typeYourResponse": "または別の回答を入力...",
|
|
254
255
|
"agent.unableToOpenPrint": "印刷プレビューを開けません",
|
|
255
256
|
"agent.unknownError": "不明なエラー",
|
|
256
257
|
"agent.unknownTime": "不明な時刻",
|
|
@@ -378,6 +379,10 @@
|
|
|
378
379
|
"layout.searchPlaceholder": "検索...",
|
|
379
380
|
"layout.toggleNavigationMenu": "ナビゲーションメニューを切り替え",
|
|
380
381
|
"login.accept": "承認",
|
|
382
|
+
"login.inviteActionFailed": "この招待を更新できませんでした。リストを更新しました。",
|
|
383
|
+
"login.inviteRole": "ロール: {{role}}",
|
|
384
|
+
"login.invitedBy": "招待者: {{name}}",
|
|
385
|
+
"login.invitesIntro": "次のアカウントへの参加に招待されています。各招待を承認または拒否してください。",
|
|
381
386
|
"login.reject": "拒否",
|
|
382
387
|
"login.reviewInvites": "招待を確認",
|
|
383
388
|
"login.terminal.account": "アカウント",
|
package/src/i18n/locales/ko.json
CHANGED
|
@@ -249,8 +249,9 @@
|
|
|
249
249
|
"agent.thinking": "생각 중...",
|
|
250
250
|
"agent.timeout": "시간 초과",
|
|
251
251
|
"agent.toggleRightSidebar": "오른쪽 사이드바 전환",
|
|
252
|
+
"agent.typeDifferentResponse": "또는 다른 응답을 입력하세요...",
|
|
252
253
|
"agent.typeYourMessage": "메시지를 입력하세요...",
|
|
253
|
-
"agent.typeYourResponse": "응답을 입력하세요...",
|
|
254
|
+
"agent.typeYourResponse": "또는 다른 응답을 입력하세요...",
|
|
254
255
|
"agent.unableToOpenPrint": "인쇄 미리보기를 열 수 없습니다",
|
|
255
256
|
"agent.unknownError": "알 수 없는 오류",
|
|
256
257
|
"agent.unknownTime": "알 수 없는 시간",
|
|
@@ -378,6 +379,10 @@
|
|
|
378
379
|
"layout.searchPlaceholder": "검색...",
|
|
379
380
|
"layout.toggleNavigationMenu": "탐색 메뉴 전환",
|
|
380
381
|
"login.accept": "수락",
|
|
382
|
+
"login.inviteActionFailed": "이 초대를 업데이트할 수 없습니다. 목록을 새로 고쳤습니다.",
|
|
383
|
+
"login.inviteRole": "역할: {{role}}",
|
|
384
|
+
"login.invitedBy": "초대한 사람: {{name}}",
|
|
385
|
+
"login.invitesIntro": "다음 계정에 참여하도록 초대받았습니다. 각 초대를 수락하거나 거절하세요.",
|
|
381
386
|
"login.reject": "거부",
|
|
382
387
|
"login.reviewInvites": "초대 검토",
|
|
383
388
|
"login.terminal.account": "계정",
|
package/src/i18n/locales/pt.json
CHANGED
|
@@ -251,8 +251,9 @@
|
|
|
251
251
|
"agent.thinking": "Pensando...",
|
|
252
252
|
"agent.timeout": "Tempo esgotado",
|
|
253
253
|
"agent.toggleRightSidebar": "Alternar painel lateral",
|
|
254
|
+
"agent.typeDifferentResponse": "Ou digite uma resposta diferente...",
|
|
254
255
|
"agent.typeYourMessage": "Digite sua mensagem...",
|
|
255
|
-
"agent.typeYourResponse": "
|
|
256
|
+
"agent.typeYourResponse": "Ou digite uma resposta diferente...",
|
|
256
257
|
"agent.unableToOpenPrint": "Não foi possível abrir a visualização de impressão",
|
|
257
258
|
"agent.unknownError": "Erro desconhecido",
|
|
258
259
|
"agent.unknownTime": "Hora desconhecida",
|
|
@@ -380,6 +381,10 @@
|
|
|
380
381
|
"layout.searchPlaceholder": "Pesquisar...",
|
|
381
382
|
"layout.toggleNavigationMenu": "Alternar menu de navegação",
|
|
382
383
|
"login.accept": "Aceitar",
|
|
384
|
+
"login.inviteActionFailed": "Não foi possível atualizar este convite. A lista foi atualizada.",
|
|
385
|
+
"login.inviteRole": "Função: {{role}}",
|
|
386
|
+
"login.invitedBy": "Convidado por {{name}}",
|
|
387
|
+
"login.invitesIntro": "Você foi convidado a participar das seguintes contas. Aceite ou recuse cada convite.",
|
|
383
388
|
"login.reject": "Rejeitar",
|
|
384
389
|
"login.reviewInvites": "Revisar convites",
|
|
385
390
|
"login.terminal.account": "Conta",
|
package/src/i18n/locales/ru.json
CHANGED
|
@@ -255,8 +255,9 @@
|
|
|
255
255
|
"agent.thinking": "Размышляю...",
|
|
256
256
|
"agent.timeout": "Время ожидания истекло",
|
|
257
257
|
"agent.toggleRightSidebar": "Переключить правую панель",
|
|
258
|
+
"agent.typeDifferentResponse": "Или введите другой ответ...",
|
|
258
259
|
"agent.typeYourMessage": "Введите сообщение...",
|
|
259
|
-
"agent.typeYourResponse": "
|
|
260
|
+
"agent.typeYourResponse": "Или введите другой ответ...",
|
|
260
261
|
"agent.unableToOpenPrint": "Не удалось открыть предпросмотр печати",
|
|
261
262
|
"agent.unknownError": "Неизвестная ошибка",
|
|
262
263
|
"agent.unknownTime": "Неизвестное время",
|
|
@@ -384,6 +385,10 @@
|
|
|
384
385
|
"layout.searchPlaceholder": "Поиск...",
|
|
385
386
|
"layout.toggleNavigationMenu": "Переключить меню навигации",
|
|
386
387
|
"login.accept": "Принять",
|
|
388
|
+
"login.inviteActionFailed": "Не удалось обновить это приглашение. Список обновлён.",
|
|
389
|
+
"login.inviteRole": "Роль: {{role}}",
|
|
390
|
+
"login.invitedBy": "Пригласил(а): {{name}}",
|
|
391
|
+
"login.invitesIntro": "Вас пригласили присоединиться к следующим аккаунтам. Примите или отклоните каждое приглашение.",
|
|
387
392
|
"login.reject": "Отклонить",
|
|
388
393
|
"login.reviewInvites": "Просмотреть приглашения",
|
|
389
394
|
"login.terminal.account": "Аккаунт",
|
package/src/i18n/locales/tr.json
CHANGED
|
@@ -249,8 +249,9 @@
|
|
|
249
249
|
"agent.thinking": "Düşünüyor...",
|
|
250
250
|
"agent.timeout": "Zaman aşımına uğradı",
|
|
251
251
|
"agent.toggleRightSidebar": "Sağ kenar çubuğunu aç/kapat",
|
|
252
|
+
"agent.typeDifferentResponse": "Ya da farklı bir yanıt yazın...",
|
|
252
253
|
"agent.typeYourMessage": "Mesajınızı yazın...",
|
|
253
|
-
"agent.typeYourResponse": "
|
|
254
|
+
"agent.typeYourResponse": "Ya da farklı bir yanıt yazın...",
|
|
254
255
|
"agent.unableToOpenPrint": "Yazdırma önizlemesi açılamadı",
|
|
255
256
|
"agent.unknownError": "Bilinmeyen hata",
|
|
256
257
|
"agent.unknownTime": "Bilinmeyen zaman",
|
|
@@ -378,6 +379,10 @@
|
|
|
378
379
|
"layout.searchPlaceholder": "Ara...",
|
|
379
380
|
"layout.toggleNavigationMenu": "Gezinme menüsünü aç veya kapat",
|
|
380
381
|
"login.accept": "Kabul Et",
|
|
382
|
+
"login.inviteActionFailed": "Bu davet güncellenemedi. Liste yenilendi.",
|
|
383
|
+
"login.inviteRole": "Rol: {{role}}",
|
|
384
|
+
"login.invitedBy": "Davet eden: {{name}}",
|
|
385
|
+
"login.invitesIntro": "Aşağıdaki hesaplara katılmaya davet edildiniz. Her daveti kabul edin veya reddedin.",
|
|
381
386
|
"login.reject": "Reddet",
|
|
382
387
|
"login.reviewInvites": "Davetleri İncele",
|
|
383
388
|
"login.terminal.account": "Hesap",
|
|
@@ -249,8 +249,9 @@
|
|
|
249
249
|
"agent.thinking": "思考中...",
|
|
250
250
|
"agent.timeout": "已逾時",
|
|
251
251
|
"agent.toggleRightSidebar": "切換右側邊欄",
|
|
252
|
+
"agent.typeDifferentResponse": "或輸入其他回覆...",
|
|
252
253
|
"agent.typeYourMessage": "輸入訊息...",
|
|
253
|
-
"agent.typeYourResponse": "
|
|
254
|
+
"agent.typeYourResponse": "或輸入其他回覆...",
|
|
254
255
|
"agent.unableToOpenPrint": "無法開啟列印預覽",
|
|
255
256
|
"agent.unknownError": "未知錯誤",
|
|
256
257
|
"agent.unknownTime": "未知時間",
|
|
@@ -378,6 +379,10 @@
|
|
|
378
379
|
"layout.searchPlaceholder": "搜尋...",
|
|
379
380
|
"layout.toggleNavigationMenu": "切換導覽選單",
|
|
380
381
|
"login.accept": "接受",
|
|
382
|
+
"login.inviteActionFailed": "無法更新此邀請。清單已重新整理。",
|
|
383
|
+
"login.inviteRole": "角色:{{role}}",
|
|
384
|
+
"login.invitedBy": "邀請人:{{name}}",
|
|
385
|
+
"login.invitesIntro": "您已受邀加入以下帳戶。請接受或拒絕每個邀請。",
|
|
381
386
|
"login.reject": "拒絕",
|
|
382
387
|
"login.reviewInvites": "查看邀請",
|
|
383
388
|
"login.terminal.account": "帳戶",
|
package/src/i18n/locales/zh.json
CHANGED
|
@@ -249,8 +249,9 @@
|
|
|
249
249
|
"agent.thinking": "思考中...",
|
|
250
250
|
"agent.timeout": "已超时",
|
|
251
251
|
"agent.toggleRightSidebar": "切换右侧边栏",
|
|
252
|
+
"agent.typeDifferentResponse": "或输入其他回复...",
|
|
252
253
|
"agent.typeYourMessage": "输入消息...",
|
|
253
|
-
"agent.typeYourResponse": "
|
|
254
|
+
"agent.typeYourResponse": "或输入其他回复...",
|
|
254
255
|
"agent.unableToOpenPrint": "无法打开打印预览",
|
|
255
256
|
"agent.unknownError": "未知错误",
|
|
256
257
|
"agent.unknownTime": "未知时间",
|
|
@@ -378,6 +379,10 @@
|
|
|
378
379
|
"layout.searchPlaceholder": "搜索...",
|
|
379
380
|
"layout.toggleNavigationMenu": "切换导航菜单",
|
|
380
381
|
"login.accept": "接受",
|
|
382
|
+
"login.inviteActionFailed": "无法更新此邀请。列表已刷新。",
|
|
383
|
+
"login.inviteRole": "角色:{{role}}",
|
|
384
|
+
"login.invitedBy": "邀请人:{{name}}",
|
|
385
|
+
"login.invitesIntro": "您已被邀请加入以下账户。请接受或拒绝每个邀请。",
|
|
381
386
|
"login.reject": "拒绝",
|
|
382
387
|
"login.reviewInvites": "查看邀请",
|
|
383
388
|
"login.terminal.account": "账户",
|
package/src/i18n/rtl.ts
CHANGED
|
@@ -29,6 +29,9 @@ export const SUPPORTED_LANGUAGES = [
|
|
|
29
29
|
|
|
30
30
|
export type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number];
|
|
31
31
|
|
|
32
|
+
/** Where `LanguageProvider` persists the chosen language; the boot runtime reads it too. */
|
|
33
|
+
export const LANGUAGE_STORAGE_KEY = 'vertesia-ui-language';
|
|
34
|
+
|
|
32
35
|
export const RTL_LANGUAGES: ReadonlySet<string> = new Set(['ar', 'he', 'fa', 'ur']);
|
|
33
36
|
|
|
34
37
|
export function isRTL(lng?: string): boolean {
|
|
@@ -42,8 +45,8 @@ export function isRTL(lng?: string): boolean {
|
|
|
42
45
|
* 2. base-language fallback (`pt-BR` -> `pt`)
|
|
43
46
|
* 3. `'en'` fallback
|
|
44
47
|
*
|
|
45
|
-
* The
|
|
46
|
-
*
|
|
48
|
+
* The pre-React boot runtime (`../boot/index.ts`) reimplements this same logic
|
|
49
|
+
* in its inline script, which runs before any bundle loads.
|
|
47
50
|
*/
|
|
48
51
|
export function resolveLanguage(raw: string | undefined | null): SupportedLanguage {
|
|
49
52
|
if (!raw) return 'en';
|
|
@@ -280,10 +280,17 @@ export function UserSessionProvider({ children, loadOnboardingStatus = false }:
|
|
|
280
280
|
})
|
|
281
281
|
.catch((err) => {
|
|
282
282
|
if (surfaceAuthError(err)) return;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
283
|
+
// A customer-domain user without an invite is an expected sign-in outcome, already
|
|
284
|
+
// logged at warn where the 403 is received.
|
|
285
|
+
const inviteRequired =
|
|
286
|
+
err instanceof Error &&
|
|
287
|
+
err.message === 'Customer-domain user requires an invite to join';
|
|
288
|
+
if (!inviteRequired) {
|
|
289
|
+
console.error('Unexpected failure while fetching a user token', err);
|
|
290
|
+
Env.logger.error('Unexpected failure while fetching a user token', {
|
|
291
|
+
vertesia: { account_id: selectedAccount, project_id: selectedProject, error: err },
|
|
292
|
+
});
|
|
293
|
+
}
|
|
287
294
|
session.logout();
|
|
288
295
|
session.isLoading = false;
|
|
289
296
|
session.authError = err;
|
|
@@ -116,17 +116,7 @@ function identityFromAcceptedToken(token: string): AuthenticatedIdentity | undef
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
export
|
|
120
|
-
// A URL selection owns the whole pair: never attach an unrelated configured account/project.
|
|
121
|
-
const hasUrlScope = currentUrl.searchParams.has('a') || currentUrl.searchParams.has('p');
|
|
122
|
-
const defaults = hasUrlScope ? undefined : Env.defaultAuthSelection;
|
|
123
|
-
const urlAccount = currentUrl.searchParams.get('a') ?? defaults?.accountId;
|
|
124
|
-
const urlProject = currentUrl.searchParams.get('p') ?? defaults?.projectId;
|
|
125
|
-
// A project alone identifies its account, so the stored selection only fills in a missing project.
|
|
126
|
-
const stored = urlProject === undefined ? readScopeSelection(urlAccount) : undefined;
|
|
127
|
-
|
|
128
|
-
return { accountId: urlAccount ?? stored?.accountId, projectId: urlProject ?? stored?.projectId };
|
|
129
|
-
}
|
|
119
|
+
export { resolveAuthSelection } from '../scopeSelection';
|
|
130
120
|
|
|
131
121
|
function decodeToken(token: string): AuthTokenPayload {
|
|
132
122
|
return jwtDecode(token) as AuthTokenPayload;
|
|
@@ -92,10 +92,9 @@ export async function setFirebaseTenant(tenantEmail?: string) {
|
|
|
92
92
|
// Handle HTTP error responses
|
|
93
93
|
if (!response.ok) {
|
|
94
94
|
// If the error is 404 Not Found, no need to retry
|
|
95
|
+
// How older servers answered "this address has no SSO tenant": an ordinary outcome.
|
|
95
96
|
if (response.status === 404) {
|
|
96
|
-
Env.logger.
|
|
97
|
-
vertesia: { status: response.status },
|
|
98
|
-
});
|
|
97
|
+
Env.logger.debug('No Firebase tenant for this address; using the default tenant');
|
|
99
98
|
return;
|
|
100
99
|
}
|
|
101
100
|
|
|
@@ -103,10 +102,14 @@ export async function setFirebaseTenant(tenantEmail?: string) {
|
|
|
103
102
|
throw new Error(errorData?.error ?? `HTTP error ${response.status}`);
|
|
104
103
|
}
|
|
105
104
|
|
|
106
|
-
// Successfully got a response, parse it
|
|
107
|
-
const data = (await response.json()) as UIResolvedTenant;
|
|
105
|
+
// Successfully got a response, parse it. `null` means the address has no SSO tenant.
|
|
106
|
+
const data = (await response.json()) as UIResolvedTenant | null;
|
|
107
|
+
if (data === null) {
|
|
108
|
+
Env.logger.debug('No Firebase tenant for this address; using the default tenant');
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
108
111
|
|
|
109
|
-
if (data
|
|
112
|
+
if (data.firebaseTenantId) {
|
|
110
113
|
const auth = getFirebaseAuth();
|
|
111
114
|
auth.tenantId = data.firebaseTenantId;
|
|
112
115
|
Env.firebase.providerType = data.provider ?? 'oidc';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AuthTokenPayload, REQUESTED_SCOPE_UNAVAILABLE_ERROR_CODE } from '@vertesia/common';
|
|
2
2
|
import { Env } from '@vertesia/ui/env';
|
|
3
3
|
import { jwtDecode } from 'jwt-decode';
|
|
4
|
+
import { forgetRejectedScopeSelection, resolveAuthSelection, type ScopeSelection } from '../scopeSelection';
|
|
4
5
|
import { markCentralAuthRoundTripStarted } from './authRoundTrip';
|
|
5
6
|
import { verifyAuthState } from './authState';
|
|
6
7
|
import { usesGatewaySession } from './gateway';
|
|
@@ -12,7 +13,14 @@ const MAX_TRANSACTION_AGE = 10 * 60_000;
|
|
|
12
13
|
let pending: Promise<string> | undefined;
|
|
13
14
|
// Long-lived credentials never enter browser storage. A reload resumes via the broker when access expires.
|
|
14
15
|
let refreshSession:
|
|
15
|
-
| {
|
|
16
|
+
| {
|
|
17
|
+
token: string;
|
|
18
|
+
clientId: string;
|
|
19
|
+
issuer: string;
|
|
20
|
+
resource?: string;
|
|
21
|
+
tokenEndpoint: string;
|
|
22
|
+
revocationEndpoint?: string;
|
|
23
|
+
}
|
|
16
24
|
| undefined;
|
|
17
25
|
|
|
18
26
|
export class OAuthLoginError extends Error {}
|
|
@@ -60,7 +68,10 @@ interface Transaction {
|
|
|
60
68
|
clientId: string;
|
|
61
69
|
redirectUri: string;
|
|
62
70
|
issuer: string;
|
|
71
|
+
resource?: string;
|
|
63
72
|
target: string;
|
|
73
|
+
rememberedScope?: ScopeSelection;
|
|
74
|
+
retryScope?: ScopeSelection;
|
|
64
75
|
}
|
|
65
76
|
|
|
66
77
|
export function clearAppOAuth(): void {
|
|
@@ -87,7 +98,14 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
87
98
|
const redirectUri = redirect.toString();
|
|
88
99
|
if (new URL(redirectUri).origin !== window.location.origin) throw new Error('OAuth callback must be same-origin');
|
|
89
100
|
const issuer = (config.issuer ? httpsUrl(config.issuer).toString() : Env.endpoints.sts).replace(/\/+$/, '');
|
|
90
|
-
|
|
101
|
+
// A token is issued for one audience. The default audience follows the issuer, which is already part of every
|
|
102
|
+
// stored credential's identity; a configured one is recorded alongside it, so changing it never reuses a token,
|
|
103
|
+
// refresh session or login transaction issued for the previous audience.
|
|
104
|
+
const configuredResource = config.resource ? httpsUrl(config.resource).toString() : undefined;
|
|
105
|
+
const sameClient = (stored: { clientId: string; issuer: string; resource?: string }) =>
|
|
106
|
+
stored.clientId === clientId && stored.issuer === issuer && stored.resource === configuredResource;
|
|
107
|
+
let current = new URL(window.location.href);
|
|
108
|
+
let { accountId, projectId } = resolveAuthSelection(current);
|
|
91
109
|
const callback = current.origin + current.pathname === new URL(redirectUri).origin + new URL(redirectUri).pathname;
|
|
92
110
|
const state = callback ? current.searchParams.get('state') : null;
|
|
93
111
|
const code = callback ? current.searchParams.get('code') : null;
|
|
@@ -101,15 +119,26 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
101
119
|
if (
|
|
102
120
|
!transaction ||
|
|
103
121
|
transaction.state !== state ||
|
|
104
|
-
transaction
|
|
122
|
+
!sameClient(transaction) ||
|
|
105
123
|
transaction.redirectUri !== redirectUri ||
|
|
106
|
-
transaction.issuer !== issuer ||
|
|
107
124
|
Date.now() - transaction.created > MAX_TRANSACTION_AGE ||
|
|
108
125
|
transaction.created > Date.now()
|
|
109
126
|
) {
|
|
110
127
|
throw new Error('Invalid or expired OAuth login state');
|
|
111
128
|
}
|
|
112
|
-
if (error
|
|
129
|
+
if (error === REQUESTED_SCOPE_UNAVAILABLE_ERROR_CODE && transaction.rememberedScope?.accountId) {
|
|
130
|
+
const target = new URL(transaction.target);
|
|
131
|
+
if (target.origin !== window.location.origin) throw new Error('Invalid OAuth return target');
|
|
132
|
+
forgetRejectedScopeSelection(transaction.rememberedScope.accountId, transaction.rememberedScope.projectId);
|
|
133
|
+
clearAppOAuth();
|
|
134
|
+
current = target;
|
|
135
|
+
window.history.replaceState(window.history.state, '', current);
|
|
136
|
+
accountId = transaction.retryScope?.accountId;
|
|
137
|
+
projectId = undefined;
|
|
138
|
+
transaction = undefined;
|
|
139
|
+
} else if (error || !code) {
|
|
140
|
+
throw new Error(`Application sign-in was not completed (${error || 'missing code'})`);
|
|
141
|
+
}
|
|
113
142
|
} else {
|
|
114
143
|
const raw = sessionStorage.getItem(TOKEN_KEY);
|
|
115
144
|
if (raw) {
|
|
@@ -117,29 +146,25 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
117
146
|
token: string;
|
|
118
147
|
clientId: string;
|
|
119
148
|
issuer: string;
|
|
149
|
+
resource?: string;
|
|
120
150
|
refreshToken?: string;
|
|
121
151
|
};
|
|
122
152
|
const claims = jwtDecode<AuthTokenPayload>(cached.token);
|
|
123
153
|
if (
|
|
124
154
|
config.offlineAccess &&
|
|
125
|
-
cached
|
|
126
|
-
|
|
127
|
-
(!
|
|
128
|
-
(!current.searchParams.get('a') || claims.account?.id === current.searchParams.get('a'))
|
|
155
|
+
sameClient(cached) &&
|
|
156
|
+
(!projectId || claims.project?.id === projectId) &&
|
|
157
|
+
(!accountId || claims.account?.id === accountId)
|
|
129
158
|
)
|
|
130
|
-
refreshCredential =
|
|
131
|
-
refreshSession?.clientId === clientId && refreshSession.issuer === issuer
|
|
132
|
-
? refreshSession.token
|
|
133
|
-
: undefined;
|
|
159
|
+
refreshCredential = refreshSession && sameClient(refreshSession) ? refreshSession.token : undefined;
|
|
134
160
|
// Discard credentials persisted by older SDK versions rather than loading them into the new session.
|
|
135
161
|
if (cached.refreshToken) sessionStorage.removeItem(TOKEN_KEY);
|
|
136
162
|
if (
|
|
137
|
-
cached
|
|
138
|
-
cached.issuer === issuer &&
|
|
163
|
+
sameClient(cached) &&
|
|
139
164
|
!forceRefresh &&
|
|
140
165
|
claims.exp > Date.now() / 1000 + (config.offlineAccess ? 300 : 30) &&
|
|
141
|
-
(!
|
|
142
|
-
(!
|
|
166
|
+
(!projectId || claims.project?.id === projectId) &&
|
|
167
|
+
(!accountId || claims.account?.id === accountId)
|
|
143
168
|
) {
|
|
144
169
|
return cached.token;
|
|
145
170
|
}
|
|
@@ -163,7 +188,7 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
163
188
|
const tokenEndpoint = httpsUrl(metadata.token_endpoint);
|
|
164
189
|
const revocationEndpoint =
|
|
165
190
|
metadata.revocation_endpoint === undefined ? undefined : httpsUrl(metadata.revocation_endpoint).toString();
|
|
166
|
-
const resource =
|
|
191
|
+
const resource = configuredResource ?? new URL(metadata.issuer).toString();
|
|
167
192
|
if (refreshCredential) {
|
|
168
193
|
try {
|
|
169
194
|
const response = await fetch(tokenEndpoint, {
|
|
@@ -189,8 +214,8 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
189
214
|
claims.iss.replace(/\/+$/, '') !== issuer ||
|
|
190
215
|
claims.client_id !== clientId ||
|
|
191
216
|
claims.exp <= Date.now() / 1000 ||
|
|
192
|
-
(!!
|
|
193
|
-
(!!
|
|
217
|
+
(!!accountId && claims.account?.id !== accountId) ||
|
|
218
|
+
(!!projectId && claims.project?.id !== projectId)
|
|
194
219
|
)
|
|
195
220
|
throw new OAuthLoginError('Invalid OAuth refresh identity');
|
|
196
221
|
sessionStorage.setItem(
|
|
@@ -199,12 +224,14 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
199
224
|
token: grant.access_token,
|
|
200
225
|
clientId,
|
|
201
226
|
issuer,
|
|
227
|
+
resource: configuredResource,
|
|
202
228
|
}),
|
|
203
229
|
);
|
|
204
230
|
refreshSession = {
|
|
205
231
|
token: grant.refresh_token ?? refreshCredential,
|
|
206
232
|
clientId,
|
|
207
233
|
issuer,
|
|
234
|
+
resource: configuredResource,
|
|
208
235
|
tokenEndpoint: tokenEndpoint.toString(),
|
|
209
236
|
revocationEndpoint,
|
|
210
237
|
};
|
|
@@ -246,6 +273,7 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
246
273
|
token: grant.access_token,
|
|
247
274
|
clientId,
|
|
248
275
|
issuer,
|
|
276
|
+
resource: configuredResource,
|
|
249
277
|
}),
|
|
250
278
|
);
|
|
251
279
|
refreshSession =
|
|
@@ -254,6 +282,7 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
254
282
|
token: grant.refresh_token,
|
|
255
283
|
clientId,
|
|
256
284
|
issuer,
|
|
285
|
+
resource: configuredResource,
|
|
257
286
|
tokenEndpoint: tokenEndpoint.toString(),
|
|
258
287
|
revocationEndpoint,
|
|
259
288
|
}
|
|
@@ -277,6 +306,13 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
277
306
|
throw new Error('Application CIMD does not allow this callback');
|
|
278
307
|
if (!config.scopes && document.scope) scopes = document.scope.split(/\s+/);
|
|
279
308
|
}
|
|
309
|
+
const explicitScope =
|
|
310
|
+
current.searchParams.has('a') || current.searchParams.has('p')
|
|
311
|
+
? {
|
|
312
|
+
accountId: current.searchParams.get('a') ?? undefined,
|
|
313
|
+
projectId: current.searchParams.get('p') ?? undefined,
|
|
314
|
+
}
|
|
315
|
+
: Env.defaultAuthSelection;
|
|
280
316
|
const verifier = randomValue();
|
|
281
317
|
const next: Transaction = {
|
|
282
318
|
state: randomValue(),
|
|
@@ -284,7 +320,13 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
284
320
|
clientId,
|
|
285
321
|
redirectUri,
|
|
286
322
|
issuer,
|
|
323
|
+
resource: configuredResource,
|
|
287
324
|
target: current.toString(),
|
|
325
|
+
rememberedScope:
|
|
326
|
+
accountId && explicitScope?.projectId === undefined && (!explicitScope?.accountId || projectId)
|
|
327
|
+
? { accountId, projectId }
|
|
328
|
+
: undefined,
|
|
329
|
+
retryScope: explicitScope?.accountId ? { accountId: explicitScope.accountId } : undefined,
|
|
288
330
|
created: Date.now(),
|
|
289
331
|
};
|
|
290
332
|
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));
|
|
@@ -302,10 +344,8 @@ async function acquireToken(forceRefresh = false): Promise<string> {
|
|
|
302
344
|
: scopes.filter((s) => s !== 'offline_access')
|
|
303
345
|
).join(' '),
|
|
304
346
|
);
|
|
305
|
-
|
|
306
|
-
if (
|
|
307
|
-
const project = current.searchParams.get('p');
|
|
308
|
-
if (project) authorize.searchParams.set('project_id', project);
|
|
347
|
+
if (accountId) authorize.searchParams.set('account_id', accountId);
|
|
348
|
+
if (projectId) authorize.searchParams.set('project_id', projectId);
|
|
309
349
|
sessionStorage.setItem(TRANSACTION_KEY, JSON.stringify(next));
|
|
310
350
|
markCentralAuthRoundTripStarted();
|
|
311
351
|
window.location.replace(authorize.toString());
|