@adminide-stack/yantra-mobile 12.0.68 → 12.0.69-alpha.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/lib/compute.js +8 -3
- package/lib/compute.js.map +1 -1
- package/lib/features/apps/mobileAppCatalog.js +9 -0
- package/lib/features/apps/mobileAppCatalog.js.map +1 -1
- package/lib/features/messaging/RegistrationScreen.js +358 -0
- package/lib/features/messaging/RegistrationScreen.js.map +1 -0
- package/lib/features/messaging/chatOperations.js +20 -0
- package/lib/features/messaging/chatOperations.js.map +1 -0
- package/lib/features/messaging/chatRegistrationStorage.js +1 -0
- package/lib/features/messaging/chatRegistrationStorage.js.map +1 -0
- package/lib/features/messaging/phoneNumbers.js +102 -0
- package/lib/features/messaging/phoneNumbers.js.map +1 -0
- package/lib/features/messaging/useChatViewer.js +16 -20
- package/lib/features/messaging/useChatViewer.js.map +1 -1
- package/lib/features/messaging/usePhoneVerification.js +147 -0
- package/lib/features/messaging/usePhoneVerification.js.map +1 -0
- package/lib/features/messaging/useYantraChatMembership.js +75 -0
- package/lib/features/messaging/useYantraChatMembership.js.map +1 -0
- package/lib/features/messaging/yantraChatOrg.js +17 -0
- package/lib/features/messaging/yantraChatOrg.js.map +1 -0
- package/lib/hooks/usePrerequisiteIds.js +5 -6
- package/lib/hooks/usePrerequisiteIds.js.map +1 -1
- package/lib/routes.json +8 -3
- package/lib/screens/ChatNative/index.js +72 -20
- package/lib/screens/ChatNative/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,32 +1,28 @@
|
|
|
1
|
-
import {useMemo}from'react';import {useSelector}from'react-redux';import {userSelector}from'@adminide-stack/user-auth0-client';import {
|
|
2
|
-
var _a
|
|
1
|
+
import {useMemo}from'react';import {useSelector}from'react-redux';import {userSelector}from'@adminide-stack/user-auth0-client';import {pickPrimaryDisplayName,pickAuthPicture}from'../../utils/authUserDisplay.js';import {useYantraChatMembership}from'./useYantraChatMembership.js';import {YANTRA_CHAT_ORG_SLUG}from'./yantraChatOrg.js';function useChatViewer() {
|
|
2
|
+
var _a;
|
|
3
3
|
const authUser = useSelector(userSelector);
|
|
4
|
-
const
|
|
5
|
-
orgName,
|
|
6
|
-
orgLoading
|
|
7
|
-
} = usePrerequisiteIds();
|
|
8
|
-
const {
|
|
9
|
-
data,
|
|
10
|
-
loading: profileLoading,
|
|
11
|
-
error: profileError
|
|
12
|
-
} = useAccountProfileQuery({
|
|
13
|
-
fetchPolicy: "cache-and-network",
|
|
14
|
-
errorPolicy: "all"
|
|
15
|
-
});
|
|
16
|
-
const userId = (_c = (_b = (_a = data == null ? void 0 : data.accountProfile) == null ? void 0 : _a.user) == null ? void 0 : _b.id) != null ? _c : null;
|
|
4
|
+
const userId = (_a = authUser == null ? void 0 : authUser.id) != null ? _a : null;
|
|
17
5
|
const displayName = useMemo(() => pickPrimaryDisplayName(authUser), [authUser]);
|
|
18
6
|
const avatarUrl = useMemo(() => pickAuthPicture(authUser), [authUser]);
|
|
7
|
+
const membership = useYantraChatMembership(userId, displayName);
|
|
8
|
+
const registrationStatus = membership.phoneE164 ? "registered" : membership.loading ? "registering" : "not-registered";
|
|
19
9
|
const viewer = useMemo(() => userId ? {
|
|
20
10
|
userId,
|
|
21
11
|
displayName,
|
|
22
12
|
avatarUrl,
|
|
23
|
-
orgName:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
orgName: YANTRA_CHAT_ORG_SLUG,
|
|
14
|
+
phoneE164: membership.phoneE164,
|
|
15
|
+
registrationStatus
|
|
16
|
+
} : null, [userId, displayName, avatarUrl, membership.phoneE164, registrationStatus]);
|
|
17
|
+
const ready = Boolean(authUser) && !membership.loading;
|
|
18
|
+
const error = membership.error || (!viewer && ready ? "Could not load your account." : null);
|
|
27
19
|
return {
|
|
28
20
|
viewer,
|
|
29
21
|
error,
|
|
30
|
-
ready
|
|
22
|
+
ready,
|
|
23
|
+
needsRegistration: membership.needsRegistration,
|
|
24
|
+
membershipLoading: membership.loading,
|
|
25
|
+
registerForChat: membership.register,
|
|
26
|
+
refreshMembership: membership.refresh
|
|
31
27
|
};
|
|
32
28
|
}export{useChatViewer};//# sourceMappingURL=useChatViewer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatViewer.js","sources":["../../../src/features/messaging/useChatViewer.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"useChatViewer.js","sources":["../../../src/features/messaging/useChatViewer.ts"],"sourcesContent":["import { useMemo } from 'react';\nimport { useSelector } from 'react-redux';\nimport type { IUserState } from '@adminide-stack/core';\nimport { Store, userSelector } from '@adminide-stack/user-auth0-client';\nimport { pickAuthPicture, pickPrimaryDisplayName } from '../../utils/authUserDisplay';\nimport type { ChatViewer, ChatRegistrationStatus } from './chatHost';\nimport { useYantraChatMembership } from './useYantraChatMembership';\nimport { YANTRA_CHAT_ORG_SLUG } from './yantraChatOrg';\n\nexport interface ChatViewerState {\n viewer: ChatViewer | null;\n error: string | null;\n ready: boolean;\n needsRegistration: boolean;\n membershipLoading: boolean;\n registerForChat: (phoneE164: string) => Promise<string>;\n refreshMembership: () => Promise<void>;\n}\n\nexport function useChatViewer(): ChatViewerState {\n const authUser = useSelector<Store.Auth, IUserState>(userSelector);\n const userId = authUser?.id ?? null;\n const displayName = useMemo(() => pickPrimaryDisplayName(authUser), [authUser]);\n const avatarUrl = useMemo(() => pickAuthPicture(authUser), [authUser]);\n\n const membership = useYantraChatMembership(userId, displayName);\n\n const registrationStatus: ChatRegistrationStatus = membership.phoneE164\n ? 'registered'\n : membership.loading\n ? 'registering'\n : 'not-registered';\n\n const viewer = useMemo<ChatViewer | null>(\n () =>\n userId\n ? {\n userId,\n displayName,\n avatarUrl,\n orgName: YANTRA_CHAT_ORG_SLUG,\n phoneE164: membership.phoneE164,\n registrationStatus,\n }\n : null,\n [userId, displayName, avatarUrl, membership.phoneE164, registrationStatus],\n );\n\n const ready = Boolean(authUser) && !membership.loading;\n\n const error = membership.error || (!viewer && ready ? 'Could not load your account.' : null);\n\n return {\n viewer,\n error,\n ready,\n needsRegistration: membership.needsRegistration,\n membershipLoading: membership.loading,\n registerForChat: membership.register,\n refreshMembership: membership.refresh,\n };\n}\n"],"names":[],"mappings":"4UAiBO,SAAS,aAAiC,GAAA;AAjBjD,EAAA,IAAA,EAAA;AAkBE,EAAM,MAAA,QAAA,GAAW,YAAoC,YAAY,CAAA;AACjE,EAAM,MAAA,MAAA,GAAA,CAAS,EAAU,GAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAA,EAAA,KAAV,IAAgB,GAAA,EAAA,GAAA,IAAA;AAC/B,EAAM,MAAA,WAAA,GAAc,QAAQ,MAAM,sBAAA,CAAuB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AAC9E,EAAM,MAAA,SAAA,GAAY,QAAQ,MAAM,eAAA,CAAgB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AACrE,EAAM,MAAA,UAAA,GAAa,uBAAwB,CAAA,MAAA,EAAQ,WAAW,CAAA;AAC9D,EAAA,MAAM,qBAA6C,UAAW,CAAA,SAAA,GAAY,YAAe,GAAA,UAAA,CAAW,UAAU,aAAgB,GAAA,gBAAA;AAC9H,EAAM,MAAA,MAAA,GAAS,OAA2B,CAAA,MAAM,MAAS,GAAA;AAAA,IACvD,MAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAS,EAAA,oBAAA;AAAA,IACT,WAAW,UAAW,CAAA,SAAA;AAAA,IACtB;AAAA,GACF,GAAI,MAAM,CAAC,MAAA,EAAQ,aAAa,SAAW,EAAA,UAAA,CAAW,SAAW,EAAA,kBAAkB,CAAC,CAAA;AACpF,EAAA,MAAM,KAAQ,GAAA,OAAA,CAAQ,QAAQ,CAAA,IAAK,CAAC,UAAW,CAAA,OAAA;AAC/C,EAAA,MAAM,QAAQ,UAAW,CAAA,KAAA,KAAU,CAAC,MAAA,IAAU,QAAQ,8BAAiC,GAAA,IAAA,CAAA;AACvF,EAAO,OAAA;AAAA,IACL,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,mBAAmB,UAAW,CAAA,iBAAA;AAAA,IAC9B,mBAAmB,UAAW,CAAA,OAAA;AAAA,IAC9B,iBAAiB,UAAW,CAAA,QAAA;AAAA,IAC5B,mBAAmB,UAAW,CAAA;AAAA,GAChC;AACF"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {useState,useCallback}from'react';import {useSendPhoneOtpCodeMutation,useVerifyPhoneOtpCodeMutation}from'common/graphql';import {formatPhoneNumber,isValidPhoneNumber}from'./phoneNumbers.js';import {useObtainSystemToken}from'../../hooks/useObtainSystemToken.js';const CHAT_REGISTRATION_TEST_OTP = "123456";
|
|
2
|
+
function isChatTestOtpCode(code) {
|
|
3
|
+
return code.replace(/\D/g, "") === CHAT_REGISTRATION_TEST_OTP;
|
|
4
|
+
}
|
|
5
|
+
function canBypassOtpWithTestCode() {
|
|
6
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) return true;
|
|
7
|
+
return process.env.EXPO_PUBLIC_CHAT_ALLOW_TEST_OTP === "true";
|
|
8
|
+
}
|
|
9
|
+
function usePhoneVerification(defaultCountryCode) {
|
|
10
|
+
const [stage, setStage] = useState("input");
|
|
11
|
+
const [inputPhone, setInputPhone] = useState("");
|
|
12
|
+
const [countryCode, setCountryCode] = useState(defaultCountryCode);
|
|
13
|
+
const [otp, setOtp] = useState("");
|
|
14
|
+
const [verifiedPhone, setVerifiedPhone] = useState(null);
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
const [loading, setLoading] = useState(false);
|
|
17
|
+
const [testOtpMode, setTestOtpMode] = useState(false);
|
|
18
|
+
const [sendPhoneOtpMutation] = useSendPhoneOtpCodeMutation();
|
|
19
|
+
const [verifyPhoneOtpMutation] = useVerifyPhoneOtpCodeMutation();
|
|
20
|
+
const clearError = useCallback(() => setError(null), []);
|
|
21
|
+
const {
|
|
22
|
+
obtainSystemToken
|
|
23
|
+
} = useObtainSystemToken();
|
|
24
|
+
const resetToInput = useCallback(() => {
|
|
25
|
+
setStage("input");
|
|
26
|
+
setInputPhone("");
|
|
27
|
+
setOtp("");
|
|
28
|
+
setError(null);
|
|
29
|
+
setVerifiedPhone(null);
|
|
30
|
+
setTestOtpMode(false);
|
|
31
|
+
}, []);
|
|
32
|
+
const continueWithTestOtp = useCallback(() => {
|
|
33
|
+
clearError();
|
|
34
|
+
const normalized = formatPhoneNumber(inputPhone, countryCode);
|
|
35
|
+
if (!normalized || !isValidPhoneNumber(normalized)) {
|
|
36
|
+
setError("Please enter a valid mobile number");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
setTestOtpMode(true);
|
|
40
|
+
setOtp(CHAT_REGISTRATION_TEST_OTP);
|
|
41
|
+
setStage("otp");
|
|
42
|
+
}, [inputPhone, countryCode, clearError]);
|
|
43
|
+
const sendOtp = useCallback(async () => {
|
|
44
|
+
var _a;
|
|
45
|
+
clearError();
|
|
46
|
+
setTestOtpMode(false);
|
|
47
|
+
const normalized = formatPhoneNumber(inputPhone, countryCode);
|
|
48
|
+
if (!normalized || !isValidPhoneNumber(normalized)) {
|
|
49
|
+
setError("Please enter a valid mobile number");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
setLoading(true);
|
|
53
|
+
try {
|
|
54
|
+
const systemToken = await obtainSystemToken();
|
|
55
|
+
if (!systemToken) throw new Error("Unable to obtain cdecli system token");
|
|
56
|
+
const result = await sendPhoneOtpMutation({
|
|
57
|
+
variables: {
|
|
58
|
+
phoneNumber: {
|
|
59
|
+
phoneNumber: normalized
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
context: {
|
|
63
|
+
headers: {
|
|
64
|
+
"x-cdecli-system-token": systemToken
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
if (!((_a = result.data) == null ? void 0 : _a.sendPhoneOTPCode)) throw new Error("Failed to send OTP");
|
|
69
|
+
setOtp("");
|
|
70
|
+
setStage("otp");
|
|
71
|
+
setError(null);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
setError(err instanceof Error ? err.message : "Failed to send OTP");
|
|
74
|
+
} finally {
|
|
75
|
+
setLoading(false);
|
|
76
|
+
}
|
|
77
|
+
}, [inputPhone, countryCode, sendPhoneOtpMutation, clearError, obtainSystemToken]);
|
|
78
|
+
const verifyOtp = useCallback(async () => {
|
|
79
|
+
var _a;
|
|
80
|
+
clearError();
|
|
81
|
+
const code = otp.replace(/\D/g, "");
|
|
82
|
+
if (!code || code.length !== 6) {
|
|
83
|
+
setError("Please enter a valid 6-digit OTP");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const normalized = formatPhoneNumber(inputPhone, countryCode);
|
|
87
|
+
if (!normalized) {
|
|
88
|
+
setError("Please enter a valid phone number");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const useTestBypass = testOtpMode || canBypassOtpWithTestCode() && isChatTestOtpCode(code);
|
|
92
|
+
if (useTestBypass && isChatTestOtpCode(code)) {
|
|
93
|
+
setVerifiedPhone(normalized);
|
|
94
|
+
setStage("verified");
|
|
95
|
+
setTestOtpMode(false);
|
|
96
|
+
setError(null);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
setStage("verifying");
|
|
100
|
+
setLoading(true);
|
|
101
|
+
try {
|
|
102
|
+
const systemToken = await obtainSystemToken();
|
|
103
|
+
if (!systemToken) throw new Error("Unable to obtain cdecli system token");
|
|
104
|
+
const result = await verifyPhoneOtpMutation({
|
|
105
|
+
variables: {
|
|
106
|
+
phoneNumber: {
|
|
107
|
+
phoneNumber: normalized
|
|
108
|
+
},
|
|
109
|
+
otp: code
|
|
110
|
+
},
|
|
111
|
+
context: {
|
|
112
|
+
headers: {
|
|
113
|
+
"x-cdecli-system-token": systemToken
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
if (!((_a = result.data) == null ? void 0 : _a.verifyPhoneOTPCode)) throw new Error("Invalid or expired OTP");
|
|
118
|
+
setVerifiedPhone(normalized);
|
|
119
|
+
setStage("verified");
|
|
120
|
+
setTestOtpMode(false);
|
|
121
|
+
setError(null);
|
|
122
|
+
} catch (err) {
|
|
123
|
+
setError(err instanceof Error ? err.message : "Failed to verify OTP");
|
|
124
|
+
setStage("otp");
|
|
125
|
+
} finally {
|
|
126
|
+
setLoading(false);
|
|
127
|
+
}
|
|
128
|
+
}, [otp, inputPhone, countryCode, testOtpMode, verifyPhoneOtpMutation, clearError, obtainSystemToken]);
|
|
129
|
+
return {
|
|
130
|
+
stage,
|
|
131
|
+
verifiedPhone,
|
|
132
|
+
inputPhone,
|
|
133
|
+
countryCode,
|
|
134
|
+
otp,
|
|
135
|
+
error,
|
|
136
|
+
loading,
|
|
137
|
+
testOtpMode,
|
|
138
|
+
setCountryCode,
|
|
139
|
+
setInputPhone,
|
|
140
|
+
setOtp,
|
|
141
|
+
sendOtp,
|
|
142
|
+
verifyOtp,
|
|
143
|
+
continueWithTestOtp,
|
|
144
|
+
resetToInput,
|
|
145
|
+
clearError
|
|
146
|
+
};
|
|
147
|
+
}export{CHAT_REGISTRATION_TEST_OTP,usePhoneVerification};//# sourceMappingURL=usePhoneVerification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePhoneVerification.js","sources":["../../../src/features/messaging/usePhoneVerification.ts"],"sourcesContent":["/**\n * Phone number verification flow for Yantra Chat registration.\n *\n * Manages the OTP verification process for phone-number-based membership.\n * Uses adminIde's existing `sendPhoneOTP` / `verifyPhoneOtp` mutations and Auth0's\n * `passwordlessLogin` endpoint.\n *\n * Phone numbers are normalized to E.164 format and serve as the member ID.\n */\nimport { useCallback, useState } from 'react';\nimport { useSendPhoneOtpCodeMutation, useVerifyPhoneOtpCodeMutation } from 'common/graphql';\nimport { formatPhoneNumber, isValidPhoneNumber } from './phoneNumbers';\nimport { useObtainSystemToken } from '../../hooks/useObtainSystemToken';\n\n/** Fixed code for \"Continue with test OTP\" and local dev bypass (no SMS verify). */\nexport const CHAT_REGISTRATION_TEST_OTP = '123456';\n\nfunction isChatTestOtpCode(code: string): boolean {\n return code.replace(/\\D/g, '') === CHAT_REGISTRATION_TEST_OTP;\n}\n\nfunction canBypassOtpWithTestCode(): boolean {\n if (typeof __DEV__ !== 'undefined' && __DEV__) return true;\n return process.env.EXPO_PUBLIC_CHAT_ALLOW_TEST_OTP === 'true';\n}\n\nexport interface PhoneVerificationState {\n /** Current stage of the verification flow. */\n stage: 'input' | 'otp' | 'verifying' | 'verified' | 'error';\n /** The phone number in E.164 format, if successfully verified. */\n verifiedPhone: string | null;\n /** The user-entered phone (raw input, before normalization). */\n inputPhone: string;\n /** Country code (ISO-3166 alpha-2) for phone normalization. */\n countryCode: string;\n /** OTP entered by the user. */\n otp: string;\n /** Error message if verification failed. */\n error: string | null;\n /** Busy: waiting for server response. */\n loading: boolean;\n /** User chose \"Continue with test OTP\" — skip server verify when code is 123456. */\n testOtpMode: boolean;\n}\n\nexport interface PhoneVerificationActions {\n setCountryCode: (code: string) => void;\n setInputPhone: (phone: string) => void;\n setOtp: (code: string) => void;\n sendOtp: () => Promise<void>;\n verifyOtp: () => Promise<void>;\n continueWithTestOtp: () => void;\n resetToInput: () => void;\n clearError: () => void;\n}\n\nexport interface UsePhoneVerificationResult extends PhoneVerificationState, PhoneVerificationActions {}\n\n/**\n * Manages the phone verification lifecycle.\n *\n * Starts with phone input, sends OTP, then prompts for the code.\n * On success, `verifiedPhone` contains the E.164 number ready to become\n * a member ID.\n */\nexport function usePhoneVerification(defaultCountryCode?: string): UsePhoneVerificationResult {\n const [stage, setStage] = useState<PhoneVerificationState['stage']>('input');\n const [inputPhone, setInputPhone] = useState('');\n const [countryCode, setCountryCode] = useState(defaultCountryCode || 'US');\n const [otp, setOtp] = useState('');\n const [verifiedPhone, setVerifiedPhone] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [testOtpMode, setTestOtpMode] = useState(false);\n\n const [sendPhoneOtpMutation] = useSendPhoneOtpCodeMutation();\n const [verifyPhoneOtpMutation] = useVerifyPhoneOtpCodeMutation();\n\n const clearError = useCallback(() => setError(null), []);\n const { obtainSystemToken } = useObtainSystemToken();\n\n const resetToInput = useCallback(() => {\n setStage('input');\n setInputPhone('');\n setOtp('');\n setError(null);\n setVerifiedPhone(null);\n setTestOtpMode(false);\n }, []);\n\n const continueWithTestOtp = useCallback(() => {\n clearError();\n const normalized = formatPhoneNumber(inputPhone, countryCode);\n if (!normalized || !isValidPhoneNumber(normalized)) {\n setError('Please enter a valid mobile number');\n return;\n }\n setTestOtpMode(true);\n setOtp(CHAT_REGISTRATION_TEST_OTP);\n setStage('otp');\n }, [inputPhone, countryCode, clearError]);\n\n const sendOtp = useCallback(async () => {\n clearError();\n setTestOtpMode(false);\n const normalized = formatPhoneNumber(inputPhone, countryCode);\n\n if (!normalized || !isValidPhoneNumber(normalized)) {\n setError('Please enter a valid mobile number');\n return;\n }\n\n setLoading(true);\n try {\n const systemToken = await obtainSystemToken();\n if (!systemToken) throw new Error('Unable to obtain cdecli system token');\n\n const result = await sendPhoneOtpMutation({\n variables: { phoneNumber: { phoneNumber: normalized } },\n context: { headers: { 'x-cdecli-system-token': systemToken } },\n });\n\n if (!result.data?.sendPhoneOTPCode) throw new Error('Failed to send OTP');\n setOtp('');\n setStage('otp');\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send OTP');\n } finally {\n setLoading(false);\n }\n }, [inputPhone, countryCode, sendPhoneOtpMutation, clearError, obtainSystemToken]);\n\n const verifyOtp = useCallback(async () => {\n clearError();\n\n const code = otp.replace(/\\D/g, '');\n if (!code || code.length !== 6) {\n setError('Please enter a valid 6-digit OTP');\n return;\n }\n\n const normalized = formatPhoneNumber(inputPhone, countryCode);\n if (!normalized) {\n setError('Please enter a valid phone number');\n return;\n }\n\n // Test path: skip server verify (explicit test flow or dev code 123456).\n const useTestBypass = testOtpMode || (canBypassOtpWithTestCode() && isChatTestOtpCode(code));\n if (useTestBypass && isChatTestOtpCode(code)) {\n setVerifiedPhone(normalized);\n setStage('verified');\n setTestOtpMode(false);\n setError(null);\n return;\n }\n\n setStage('verifying');\n setLoading(true);\n try {\n const systemToken = await obtainSystemToken();\n if (!systemToken) throw new Error('Unable to obtain cdecli system token');\n\n const result = await verifyPhoneOtpMutation({\n variables: { phoneNumber: { phoneNumber: normalized }, otp: code },\n context: { headers: { 'x-cdecli-system-token': systemToken } },\n });\n\n if (!result.data?.verifyPhoneOTPCode) throw new Error('Invalid or expired OTP');\n setVerifiedPhone(normalized);\n setStage('verified');\n setTestOtpMode(false);\n setError(null);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to verify OTP');\n setStage('otp');\n } finally {\n setLoading(false);\n }\n }, [otp, inputPhone, countryCode, testOtpMode, verifyPhoneOtpMutation, clearError, obtainSystemToken]);\n\n return {\n stage,\n verifiedPhone,\n inputPhone,\n countryCode,\n otp,\n error,\n loading,\n testOtpMode,\n setCountryCode,\n setInputPhone,\n setOtp,\n sendOtp,\n verifyOtp,\n continueWithTestOtp,\n resetToInput,\n clearError,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {useState,useCallback,useEffect,useMemo}from'react';import {useApolloClient,gql}from'@apollo/client/index.js';import AsyncStorage from'@react-native-async-storage/async-storage';import {YANTRA_CHAT_REGISTRATION_STATUS_QUERY,REGISTER_YANTRA_CHAT_MEMBER_MUTATION}from'./chatOperations.js';import {YANTRA_CHAT_PHONE_STORAGE_KEY}from'./chatRegistrationStorage.js';const REGISTRATION_STATUS_DOCUMENT = gql(YANTRA_CHAT_REGISTRATION_STATUS_QUERY);
|
|
2
|
+
const REGISTER_MEMBER_DOCUMENT = gql(REGISTER_YANTRA_CHAT_MEMBER_MUTATION);
|
|
3
|
+
function useYantraChatMembership(userId, displayName) {
|
|
4
|
+
const client = useApolloClient();
|
|
5
|
+
const [phoneE164, setPhoneE164] = useState(null);
|
|
6
|
+
const [organizationId, setOrganizationId] = useState(null);
|
|
7
|
+
const [loading, setLoading] = useState(true);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
const refresh = useCallback(async () => {
|
|
10
|
+
var _a, _b, _c, _d;
|
|
11
|
+
if (!userId) {
|
|
12
|
+
setLoading(false);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
setError(null);
|
|
16
|
+
try {
|
|
17
|
+
const cached = await AsyncStorage.getItem(YANTRA_CHAT_PHONE_STORAGE_KEY);
|
|
18
|
+
if (cached) setPhoneE164(cached);
|
|
19
|
+
const res = await client.query({
|
|
20
|
+
query: REGISTRATION_STATUS_DOCUMENT,
|
|
21
|
+
fetchPolicy: "network-only"
|
|
22
|
+
});
|
|
23
|
+
if ((_a = res.errors) == null ? void 0 : _a.length) {
|
|
24
|
+
setError((_c = (_b = res.errors[0]) == null ? void 0 : _b.message) != null ? _c : "Could not load chat registration");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const status = (_d = res.data) == null ? void 0 : _d.yantraChatRegistrationStatus;
|
|
28
|
+
if ((status == null ? void 0 : status.registered) && status.phoneE164) {
|
|
29
|
+
setPhoneE164(status.phoneE164);
|
|
30
|
+
setOrganizationId(status.organizationId);
|
|
31
|
+
await AsyncStorage.setItem(YANTRA_CHAT_PHONE_STORAGE_KEY, status.phoneE164);
|
|
32
|
+
} else if (status && status.registered === false) {
|
|
33
|
+
setPhoneE164(null);
|
|
34
|
+
await AsyncStorage.removeItem(YANTRA_CHAT_PHONE_STORAGE_KEY);
|
|
35
|
+
}
|
|
36
|
+
} catch (err) {
|
|
37
|
+
setError(err instanceof Error ? err.message : "Could not load chat registration");
|
|
38
|
+
} finally {
|
|
39
|
+
setLoading(false);
|
|
40
|
+
}
|
|
41
|
+
}, [client, userId]);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
void refresh();
|
|
44
|
+
}, [refresh]);
|
|
45
|
+
const register = useCallback(async (phone) => {
|
|
46
|
+
var _a;
|
|
47
|
+
if (!userId) throw new Error("Not signed in");
|
|
48
|
+
setError(null);
|
|
49
|
+
const res = await client.mutate({
|
|
50
|
+
mutation: REGISTER_MEMBER_DOCUMENT,
|
|
51
|
+
variables: {
|
|
52
|
+
phoneE164: phone,
|
|
53
|
+
displayName
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const payload = (_a = res.data) == null ? void 0 : _a.registerYantraChatMember;
|
|
57
|
+
if (!(payload == null ? void 0 : payload.registered) || !payload.phoneE164) {
|
|
58
|
+
throw new Error("Registration did not complete");
|
|
59
|
+
}
|
|
60
|
+
setPhoneE164(payload.phoneE164);
|
|
61
|
+
setOrganizationId(payload.organizationId);
|
|
62
|
+
await AsyncStorage.setItem(YANTRA_CHAT_PHONE_STORAGE_KEY, payload.phoneE164);
|
|
63
|
+
return payload.phoneE164;
|
|
64
|
+
}, [client, userId, displayName]);
|
|
65
|
+
const needsRegistration = useMemo(() => Boolean(userId) && !loading && !phoneE164, [userId, loading, phoneE164]);
|
|
66
|
+
return {
|
|
67
|
+
phoneE164,
|
|
68
|
+
organizationId,
|
|
69
|
+
loading,
|
|
70
|
+
error,
|
|
71
|
+
needsRegistration,
|
|
72
|
+
register,
|
|
73
|
+
refresh
|
|
74
|
+
};
|
|
75
|
+
}export{useYantraChatMembership};//# sourceMappingURL=useYantraChatMembership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useYantraChatMembership.js","sources":["../../../src/features/messaging/useYantraChatMembership.ts"],"sourcesContent":["/**\n * Yantra Chat registration status + register mutation (issue #1312).\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { gql, useApolloClient } from '@apollo/client';\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport { REGISTER_YANTRA_CHAT_MEMBER_MUTATION, YANTRA_CHAT_REGISTRATION_STATUS_QUERY } from './chatOperations';\nimport { YANTRA_CHAT_PHONE_STORAGE_KEY } from './chatRegistrationStorage';\n\nconst REGISTRATION_STATUS_DOCUMENT = gql(YANTRA_CHAT_REGISTRATION_STATUS_QUERY);\nconst REGISTER_MEMBER_DOCUMENT = gql(REGISTER_YANTRA_CHAT_MEMBER_MUTATION);\n\ninterface RegistrationPayload {\n registered: boolean;\n phoneE164: string | null;\n memberId: string | null;\n organizationId: string;\n}\n\nexport function useYantraChatMembership(userId: string | null, displayName: string) {\n const client = useApolloClient();\n const [phoneE164, setPhoneE164] = useState<string | null>(null);\n const [organizationId, setOrganizationId] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const refresh = useCallback(async () => {\n if (!userId) {\n setLoading(false);\n return;\n }\n setError(null);\n try {\n const cached = await AsyncStorage.getItem(YANTRA_CHAT_PHONE_STORAGE_KEY);\n if (cached) setPhoneE164(cached);\n\n const res = await client.query<{ yantraChatRegistrationStatus?: RegistrationPayload }>({\n query: REGISTRATION_STATUS_DOCUMENT,\n fetchPolicy: 'network-only',\n });\n\n if (res.errors?.length) {\n setError(res.errors[0]?.message ?? 'Could not load chat registration');\n // Keep AsyncStorage + in-memory phone on transient GraphQL errors (Metro reload, backend restart).\n return;\n }\n\n const status = res.data?.yantraChatRegistrationStatus;\n if (status?.registered && status.phoneE164) {\n setPhoneE164(status.phoneE164);\n setOrganizationId(status.organizationId);\n await AsyncStorage.setItem(YANTRA_CHAT_PHONE_STORAGE_KEY, status.phoneE164);\n } else if (status && status.registered === false) {\n setPhoneE164(null);\n await AsyncStorage.removeItem(YANTRA_CHAT_PHONE_STORAGE_KEY);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Could not load chat registration');\n // Network failure: do not clear cached registration.\n } finally {\n setLoading(false);\n }\n }, [client, userId]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const register = useCallback(\n async (phone: string) => {\n if (!userId) throw new Error('Not signed in');\n setError(null);\n const res = await client.mutate<{ registerYantraChatMember?: RegistrationPayload }>({\n mutation: REGISTER_MEMBER_DOCUMENT,\n variables: { phoneE164: phone, displayName },\n });\n const payload = res.data?.registerYantraChatMember;\n if (!payload?.registered || !payload.phoneE164) {\n throw new Error('Registration did not complete');\n }\n setPhoneE164(payload.phoneE164);\n setOrganizationId(payload.organizationId);\n await AsyncStorage.setItem(YANTRA_CHAT_PHONE_STORAGE_KEY, payload.phoneE164);\n return payload.phoneE164;\n },\n [client, userId, displayName],\n );\n\n const needsRegistration = useMemo(() => Boolean(userId) && !loading && !phoneE164, [userId, loading, phoneE164]);\n\n return {\n phoneE164,\n organizationId,\n loading,\n error,\n needsRegistration,\n register,\n refresh,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {CHAT_WORKSPACE}from'common';const YANTRA_CHAT_ORG_SLUG = "yantra-chat";
|
|
2
|
+
CHAT_WORKSPACE.CHAT_ORGANIZATION_ID;
|
|
3
|
+
CHAT_WORKSPACE.CHAT_ORGANIZATION_UUID;
|
|
4
|
+
function isYantraChatOrgSlug(orgName) {
|
|
5
|
+
const trimmed = orgName == null ? void 0 : orgName.trim();
|
|
6
|
+
if (!trimmed) return false;
|
|
7
|
+
return trimmed === YANTRA_CHAT_ORG_SLUG;
|
|
8
|
+
}
|
|
9
|
+
function pickWorkspaceOrgSlug(orgs) {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
if (!(orgs == null ? void 0 : orgs.length)) return null;
|
|
12
|
+
const first = orgs.find((o) => {
|
|
13
|
+
const name = typeof (o == null ? void 0 : o.name) === "string" ? o.name.trim() : "";
|
|
14
|
+
return name.length > 0 && !isYantraChatOrgSlug(name);
|
|
15
|
+
});
|
|
16
|
+
return (_b = (_a = first == null ? void 0 : first.name) == null ? void 0 : _a.trim()) != null ? _b : null;
|
|
17
|
+
}export{YANTRA_CHAT_ORG_SLUG,isYantraChatOrgSlug,pickWorkspaceOrgSlug};//# sourceMappingURL=yantraChatOrg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yantraChatOrg.js","sources":["../../../src/features/messaging/yantraChatOrg.ts"],"sourcesContent":["import { CHAT_WORKSPACE } from 'common';\n\n/**\n * Seeded Yantra Chat organization slug (issue #1312).\n * Used only for native person-to-person chat — not the user's default workspace org.\n */\nexport const YANTRA_CHAT_ORG_SLUG = 'yantra-chat';\n\nexport const YANTRA_CHAT_ORG_MONGO_ID = CHAT_WORKSPACE.CHAT_ORGANIZATION_ID;\n\nexport const YANTRA_CHAT_ORG_UUID = CHAT_WORKSPACE.CHAT_ORGANIZATION_UUID;\n\nexport function isYantraChatOrgSlug(orgName: string | null | undefined): boolean {\n const trimmed = orgName?.trim();\n if (!trimmed) return false;\n return trimmed === YANTRA_CHAT_ORG_SLUG;\n}\n\n/** Slug, filing UUID, or Mongo id — any key the chat org is stored under. */\nexport function isYantraChatOrgKey(value: string | null | undefined): boolean {\n const trimmed = value?.trim();\n if (!trimmed) return false;\n return trimmed === YANTRA_CHAT_ORG_SLUG || trimmed === YANTRA_CHAT_ORG_UUID || trimmed === YANTRA_CHAT_ORG_MONGO_ID;\n}\n\n/** Pick a default workspace org; never use the chat-only org for Home / AI chat / settings. */\nexport function pickWorkspaceOrgSlug(\n orgs: Array<{ name?: string | null; title?: string | null } | null | undefined> | null | undefined,\n): string | null {\n if (!orgs?.length) return null;\n const first = orgs.find((o) => {\n const name = typeof o?.name === 'string' ? o.name.trim() : '';\n return name.length > 0 && !isYantraChatOrgSlug(name);\n });\n return first?.name?.trim() ?? null;\n}\n"],"names":[],"mappings":"oCAMO,MAAM,oBAAuB,GAAA;AACI,cAAe,CAAA;AACnB,cAAe,CAAA;AAC5C,SAAS,oBAAoB,OAA6C,EAAA;AAC/E,EAAA,MAAM,UAAU,OAAS,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,IAAA,EAAA;AACzB,EAAI,IAAA,CAAC,SAAgB,OAAA,KAAA;AACrB,EAAA,OAAO,OAAY,KAAA,oBAAA;AACrB;AAUO,SAAS,qBAAqB,IAGoB,EAAA;AA1BzD,EAAA,IAAA,EAAA,EAAA,EAAA;AA2BE,EAAI,IAAA,EAAC,IAAM,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,MAAA,CAAA,EAAe,OAAA,IAAA;AAC1B,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA;AAC3B,IAAM,MAAA,IAAA,GAAO,QAAO,CAAG,IAAA,IAAA,GAAA,MAAA,GAAA,CAAA,CAAA,IAAA,CAAA,KAAS,WAAW,CAAE,CAAA,IAAA,CAAK,MAAS,GAAA,EAAA;AAC3D,IAAA,OAAO,IAAK,CAAA,MAAA,GAAS,CAAK,IAAA,CAAC,oBAAoB,IAAI,CAAA;AAAA,GACpD,CAAA;AACD,EAAA,OAAA,CAAO,EAAO,GAAA,CAAA,EAAA,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,IAAA,KAAP,IAAa,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA,KAAb,IAAuB,GAAA,EAAA,GAAA,IAAA;AAChC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {DEFAULT_PRODUCTION_TAG_ID}from'@adminide-stack/core/lib/constants/defaultIds.js';import {useContextData}from'@adminide-stack/platform-client/lib/hooks/useContextData.js';import {orgChangeAction,resourceGroupChangeAction}from'@adminide-stack/platform-client/lib/redux/actions/org-action.js';import {isAuthenticatedSelector}from'@adminide-stack/user-auth0-client';import {ContributionSchemaId,ConfigurationTarget}from'common';import {useAccountProfileQuery,useGetUserOrganizationsWithDetailsQuery,useGetUserOrganizationsQuery,useGetProjectsLazyQuery,useQuickCreateProjectForAccountBkMutation,useCreateVaultMutation,useWriteSettingsMutation}from'common/graphql';import {useMemo,useEffect,useState,useCallback}from'react';import {useDispatch,useSelector}from'react-redux';import {useAccountDefaultSettings}from'./useAccountDefaultSettings.js';import {isUnhydratedCdecodeUri,toUriInput,settingsUriForAccount}from'../utils/cdecodeUri.js';const uuidToObjectId = (uuid) => uuid.replace(/-/g, "").substring(0, 24);
|
|
1
|
+
import {DEFAULT_PRODUCTION_TAG_ID}from'@adminide-stack/core/lib/constants/defaultIds.js';import {useContextData}from'@adminide-stack/platform-client/lib/hooks/useContextData.js';import {orgChangeAction,resourceGroupChangeAction}from'@adminide-stack/platform-client/lib/redux/actions/org-action.js';import {isAuthenticatedSelector}from'@adminide-stack/user-auth0-client';import {ContributionSchemaId,ConfigurationTarget}from'common';import {useAccountProfileQuery,useGetUserOrganizationsWithDetailsQuery,useGetUserOrganizationsQuery,useGetProjectsLazyQuery,useQuickCreateProjectForAccountBkMutation,useCreateVaultMutation,useWriteSettingsMutation}from'common/graphql';import {useMemo,useEffect,useState,useCallback}from'react';import {useDispatch,useSelector}from'react-redux';import {useAccountDefaultSettings}from'./useAccountDefaultSettings.js';import {isYantraChatOrgSlug,pickWorkspaceOrgSlug}from'../features/messaging/yantraChatOrg.js';import {isUnhydratedCdecodeUri,toUriInput,settingsUriForAccount}from'../utils/cdecodeUri.js';const uuidToObjectId = (uuid) => uuid.replace(/-/g, "").substring(0, 24);
|
|
2
2
|
const PROJECT_NAME = "DEFAULT_YANTRA_PROJECT";
|
|
3
3
|
const TAG_ID = uuidToObjectId(DEFAULT_PRODUCTION_TAG_ID);
|
|
4
4
|
const ACCOUNT_EXTENSION = "account";
|
|
@@ -14,10 +14,7 @@ function publishSharedResolvedProjectId(projectUuid) {
|
|
|
14
14
|
sharedProjectListeners.forEach((listener) => listener());
|
|
15
15
|
}
|
|
16
16
|
function pickDefaultOrgSlug(orgs) {
|
|
17
|
-
|
|
18
|
-
if (!(orgs == null ? void 0 : orgs.length)) return null;
|
|
19
|
-
const first = orgs.find((o) => typeof (o == null ? void 0 : o.name) === "string" && o.name.trim().length > 0);
|
|
20
|
-
return (_b = (_a = first == null ? void 0 : first.name) == null ? void 0 : _a.trim()) != null ? _b : null;
|
|
17
|
+
return pickWorkspaceOrgSlug(orgs);
|
|
21
18
|
}
|
|
22
19
|
function usePrerequisiteIds() {
|
|
23
20
|
var _a, _b, _c, _d;
|
|
@@ -107,7 +104,9 @@ function usePrerequisiteIds() {
|
|
|
107
104
|
path
|
|
108
105
|
} = toUriInput(cdecodeUri);
|
|
109
106
|
const match = path.match(/^\/([^/]+)\//);
|
|
110
|
-
|
|
107
|
+
const slug = ((_a2 = match == null ? void 0 : match[1]) == null ? void 0 : _a2.trim()) || null;
|
|
108
|
+
if (slug && isYantraChatOrgSlug(slug)) return null;
|
|
109
|
+
return slug;
|
|
111
110
|
}, [cdecodeUri]);
|
|
112
111
|
const orgName = orgFromContextSettings || orgFromAccountSettings || orgFromMembership || orgFromContextPath || null;
|
|
113
112
|
const rawSettingsProjectIdRaw = projectFromContextSettings || projectFromAccountSettings || null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePrerequisiteIds.js","sources":["../../src/hooks/usePrerequisiteIds.ts"],"sourcesContent":["import { DEFAULT_PRODUCTION_TAG_ID } from '@adminide-stack/core/lib/constants/defaultIds.js';\nimport { useContextData } from '@adminide-stack/platform-client/lib/hooks/useContextData.js';\nimport {\n orgChangeAction,\n resourceGroupChangeAction,\n} from '@adminide-stack/platform-client/lib/redux/actions/org-action.js';\nimport { isAuthenticatedSelector } from '@adminide-stack/user-auth0-client';\nimport { ConfigurationTarget, ContributionSchemaId } from 'common';\nimport {\n useAccountProfileQuery,\n useCreateVaultMutation,\n useGetProjectsLazyQuery,\n useGetUserOrganizationsQuery,\n useGetUserOrganizationsWithDetailsQuery,\n useQuickCreateProjectForAccountBkMutation,\n useWriteSettingsMutation,\n} from 'common/graphql';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useAccountDefaultSettings } from './useAccountDefaultSettings';\nimport { isUnhydratedCdecodeUri, settingsUriForAccount, toUriInput } from '../utils/cdecodeUri';\n\nconst uuidToObjectId = (uuid: string) => uuid.replace(/-/g, '').substring(0, 24);\n\nconst PROJECT_NAME = 'DEFAULT_YANTRA_PROJECT';\nconst TAG_ID = uuidToObjectId(DEFAULT_PRODUCTION_TAG_ID);\n/** SystemContributionExtensionNames.Account — owns `account.default.*`. */\nconst ACCOUNT_EXTENSION = 'account';\n\n/**\n * DEV ONLY — known working project UUID for local mobile bootstrap when create/list\n * cannot resolve `projectId`. Never use on staging/prod: createSecretApiToken needs a\n * real project that resolves to a Mongo ObjectId (unknown UUID → ObjectId cast 400).\n */\nconst TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nconst ORG_RESOLVE_POLL_MS = 2000;\nconst PROFILE_POLL_MS = 1500;\n\n// ── Module-level project fix (parity with browser) ───────────────────────────\n// Several screens/hooks mount `usePrerequisiteIds` at once. Per-instance refs race\n// and can create multiple orphan projects. Keep a single-flight guard + user id so\n// adopt/create/persist runs once per account session.\n// Resolved project must also be shared — otherwise WebBuilderPrewarm can \"win\" the\n// flight and HomeScreen never sees projectId (submit stuck on \"not ready\").\nlet projectFixInFlight = false;\nlet projectFixUserId: string | null = null;\nlet sharedResolvedProjectId: string | null = null;\nconst sharedProjectListeners = new Set<() => void>();\n\nfunction publishSharedResolvedProjectId(projectUuid: string): void {\n sharedResolvedProjectId = projectUuid;\n sharedProjectListeners.forEach((listener) => listener());\n}\n\nfunction pickDefaultOrgSlug(\n orgs: Array<{ name?: string | null; title?: string | null } | null | undefined> | null | undefined,\n): string | null {\n if (!orgs?.length) return null;\n const first = orgs.find((o) => typeof o?.name === 'string' && o.name.trim().length > 0);\n return first?.name?.trim() ?? null;\n}\n\n/**\n * Org + project prerequisites for mobile (parity with browser `usePrerequisiteIds`).\n *\n * Settings use the same `account.default` config as web (`useSettingsLoader` → `useSettings` on mobile).\n * After verify-user, account-level settings (`//accounts/{id}#settings`) and org membership are polled\n * until `organization` is available, then route context is synced on Home.\n *\n * Scenario: org set but no `account.default.project` → adopt an existing project in the org\n * (or create one), persist settings, and bind resourceGroup — same as browser Scenario 2.\n */\nexport function usePrerequisiteIds() {\n const dispatch = useDispatch();\n const isAuthenticated = useSelector(isAuthenticatedSelector);\n\n const { data: contextData, complete: contextComplete } = useContextData();\n const contextLoading = !contextComplete;\n const cdecodeUri = contextData?.cdecodeUri;\n const contextUserId = contextData?.userId ?? null;\n\n const contextResourceUri = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return undefined;\n return toUriInput(cdecodeUri);\n }, [cdecodeUri]);\n\n const {\n data: accountProfileData,\n loading: userLoading,\n refetch: refetchProfile,\n } = useAccountProfileQuery({\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n skip: !isAuthenticated,\n });\n const profileUserId = accountProfileData?.accountProfile?.user?.id ?? null;\n const effectiveUserId = isAuthenticated ? profileUserId || contextUserId : null;\n\n useEffect(() => {\n if (!isAuthenticated || profileUserId) return;\n const timer = setInterval(() => {\n refetchProfile().catch(() => undefined);\n }, PROFILE_POLL_MS);\n return () => clearInterval(timer);\n }, [isAuthenticated, profileUserId, refetchProfile]);\n\n // Step 1 (web): account.default via settings loader — context cdecodeUri when hydrated\n const {\n organization: orgFromContextSettings,\n project: projectFromContextSettings,\n environment: envFromContextSettings,\n loading: contextSettingsLoading,\n refetch: refetchContextSettings,\n } = useAccountDefaultSettings({\n resourceUri: contextResourceUri,\n skip: !isAuthenticated || !contextResourceUri,\n });\n\n const accountResourceUri = useMemo(() => {\n if (!effectiveUserId || orgFromContextSettings) return undefined;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId, orgFromContextSettings]);\n\n // Mobile bootstrap: read account.default from account document before org is on the route\n const {\n organization: orgFromAccountSettings,\n project: projectFromAccountSettings,\n environment: envFromAccountSettings,\n loading: accountSettingsLoading,\n refetch: refetchAccountSettings,\n } = useAccountDefaultSettings({\n resourceUri: accountResourceUri,\n skip: !isAuthenticated || !accountResourceUri,\n });\n\n const {\n data: orgsData,\n loading: orgsLoading,\n refetch: refetchOrgs,\n } = useGetUserOrganizationsWithDetailsQuery({\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const {\n data: orgsByUserData,\n loading: orgsByUserLoading,\n refetch: refetchOrgsByUser,\n } = useGetUserOrganizationsQuery({\n variables: { userId: effectiveUserId ?? undefined },\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const orgFromMembership = useMemo(() => {\n const fromDetails = pickDefaultOrgSlug(orgsData?.getUserOrganizationsWithDetails);\n if (fromDetails) return fromDetails;\n return pickDefaultOrgSlug(orgsByUserData?.getUserOrganizations);\n }, [orgsData, orgsByUserData]);\n\n const orgFromContextPath = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return null;\n const { path } = toUriInput(cdecodeUri);\n const match = path.match(/^\\/([^/]+)\\//);\n return match?.[1]?.trim() || null;\n }, [cdecodeUri]);\n\n const orgName = orgFromContextSettings || orgFromAccountSettings || orgFromMembership || orgFromContextPath || null;\n\n const rawSettingsProjectIdRaw = projectFromContextSettings || projectFromAccountSettings || null;\n // Staging may have persisted the local testing UUID; treat it as unset so bootstrap can mint a real project.\n const rawSettingsProjectId =\n !__DEV__ && rawSettingsProjectIdRaw === TESTING_PROJECT_UUID ? null : rawSettingsProjectIdRaw;\n\n /**\n * Env tag every credential read / vault-secret resolve / system-token mint is scoped by,\n * picked on web in Account > Preferences > Workspace and persisted as\n * `account.default.environment` (parity with the browser hook). Empty — the default, and\n * every account that never picked one — keeps the static root Production tag.\n */\n const tagId = (envFromContextSettings || envFromAccountSettings || '').trim() || TAG_ID;\n\n useEffect(() => {\n if (!isAuthenticated || orgName || !effectiveUserId) return;\n const timer = setInterval(() => {\n refetchContextSettings?.()?.catch(() => undefined);\n refetchAccountSettings?.()?.catch(() => undefined);\n refetchOrgs().catch(() => undefined);\n refetchOrgsByUser().catch(() => undefined);\n }, ORG_RESOLVE_POLL_MS);\n return () => clearInterval(timer);\n }, [\n isAuthenticated,\n orgName,\n effectiveUserId,\n refetchContextSettings,\n refetchAccountSettings,\n refetchOrgs,\n refetchOrgsByUser,\n ]);\n\n const settingsProjectId = rawSettingsProjectId;\n\n const [resolvedProjectId, setResolvedProjectId] = useState<string | null>(() => sharedResolvedProjectId);\n const [isInitializingProject, setIsInitializingProject] = useState(false);\n\n // Cross-instance sync: when another hook wins the project bootstrap, adopt it.\n useEffect(() => {\n const onShared = () => {\n if (sharedResolvedProjectId) setResolvedProjectId(sharedResolvedProjectId);\n };\n sharedProjectListeners.add(onShared);\n onShared();\n return () => {\n sharedProjectListeners.delete(onShared);\n };\n }, []);\n\n // New account session → clear shared fallback so we don't leak another user's project.\n useEffect(() => {\n if (!effectiveUserId) return;\n if (projectFixUserId && projectFixUserId !== effectiveUserId) {\n sharedResolvedProjectId = null;\n projectFixInFlight = false;\n setResolvedProjectId(null);\n }\n }, [effectiveUserId]);\n\n const projectId = settingsProjectId || resolvedProjectId || sharedResolvedProjectId;\n const settingsLoading = contextSettingsLoading || accountSettingsLoading;\n // Wait for settings to settle so we don't create before an existing default loads.\n const needsProjectCreation = !settingsLoading && !!orgName && !rawSettingsProjectId && !projectId;\n\n const [fetchProjects] = useGetProjectsLazyQuery();\n const [createProject, { error: createError, loading: projectCreating }] =\n useQuickCreateProjectForAccountBkMutation();\n const [createVault, { error: vaultCreateError }] = useCreateVaultMutation();\n const [writeSettings] = useWriteSettingsMutation();\n\n const accountSettingsUri = useMemo(() => {\n if (!effectiveUserId) return null;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId]);\n\n const persistDefaults = useCallback(\n async (orgToSet: string, projectUuid: string) => {\n if (!accountSettingsUri) return;\n await writeSettings({\n variables: {\n // The URI scalar's TS type is the vscode URI class, but the wire\n // format is this serializable POJO (same shape toUriInput emits).\n editingUri:\n accountSettingsUri as unknown as import('@vscode-alt/monaco-editor/esm/vs/base/common/uri.js').URI,\n settings: {\n 'account.default.organization': orgToSet,\n 'account.default.project': projectUuid,\n },\n target: ConfigurationTarget.USER,\n schemaId: ContributionSchemaId.Configuration,\n extensionName: ACCOUNT_EXTENSION,\n },\n });\n },\n [accountSettingsUri, writeSettings],\n );\n\n const refetchDefaults = useCallback(async () => {\n await Promise.all([\n refetchContextSettings?.()?.catch(() => undefined) ?? Promise.resolve(),\n refetchAccountSettings?.()?.catch(() => undefined) ?? Promise.resolve(),\n ]);\n }, [refetchContextSettings, refetchAccountSettings]);\n\n // Scenario 2: default org present but no project → adopt existing (or create once),\n // then persist so reload / other mounts do not create orphan projects.\n useEffect(() => {\n if (!needsProjectCreation || !effectiveUserId || userLoading || !orgName) {\n return;\n }\n\n if (projectFixUserId !== effectiveUserId) {\n projectFixUserId = effectiveUserId;\n projectFixInFlight = false;\n sharedResolvedProjectId = null;\n }\n\n if (projectFixInFlight) {\n return;\n }\n\n projectFixInFlight = true;\n setIsInitializingProject(true);\n\n (async () => {\n try {\n const existing = await fetchProjects({ variables: { orgName, limit: 50 } });\n let projectUuid =\n (existing.data?.getProjects?.data || []).find((p) => p?.projectId)?.projectId ?? undefined;\n let newMongoProjectId: string | undefined;\n\n if (!projectUuid) {\n const created = await createProject({\n variables: {\n input: {\n accountId: effectiveUserId,\n projectName: PROJECT_NAME,\n },\n },\n });\n newMongoProjectId = created.data?.quickCreateProjectForAccount?.id ?? undefined;\n if (newMongoProjectId) {\n const after = await fetchProjects({ variables: { orgName, limit: 50 } });\n projectUuid =\n (after.data?.getProjects?.data || []).find((p) => p?.id === newMongoProjectId)?.projectId ??\n // createSecretApiToken accepts Mongo ObjectId directly when no UUID dashes.\n newMongoProjectId;\n await createVault({\n variables: {\n input: {\n orgName,\n projectId: newMongoProjectId,\n },\n },\n }).catch((error) =>\n console.error('[usePrerequisiteIds] Vault creation failed:', error?.message),\n );\n } else {\n console.warn('[usePrerequisiteIds] Project creation returned no id');\n }\n }\n\n if (!projectUuid) {\n if (__DEV__) {\n console.warn(\n `[usePrerequisiteIds] Could not resolve a project UUID — using testing project ${TESTING_PROJECT_UUID}`,\n );\n projectUuid = TESTING_PROJECT_UUID;\n } else {\n console.error(\n '[usePrerequisiteIds] Could not resolve a project UUID — refusing testing fallback outside __DEV__',\n );\n projectFixInFlight = false;\n return;\n }\n }\n\n setResolvedProjectId(projectUuid);\n publishSharedResolvedProjectId(projectUuid);\n await persistDefaults(orgName, projectUuid);\n dispatch(orgChangeAction({ orgName, userId: effectiveUserId }));\n dispatch(resourceGroupChangeAction({ resourceGroup: projectUuid }));\n await refetchDefaults();\n } catch (error) {\n console.error('[usePrerequisiteIds] Project bootstrap failed:', (error as Error)?.message);\n if (__DEV__) {\n console.warn(\n `[usePrerequisiteIds] Falling back to testing project ${TESTING_PROJECT_UUID} after bootstrap error`,\n );\n setResolvedProjectId(TESTING_PROJECT_UUID);\n publishSharedResolvedProjectId(TESTING_PROJECT_UUID);\n try {\n await persistDefaults(orgName, TESTING_PROJECT_UUID);\n dispatch(orgChangeAction({ orgName, userId: effectiveUserId }));\n dispatch(resourceGroupChangeAction({ resourceGroup: TESTING_PROJECT_UUID }));\n await refetchDefaults();\n } catch (persistError) {\n console.error(\n '[usePrerequisiteIds] Testing fallback persist failed:',\n (persistError as Error)?.message,\n );\n projectFixInFlight = false;\n }\n } else {\n projectFixInFlight = false;\n }\n } finally {\n setIsInitializingProject(false);\n }\n })();\n }, [\n createProject,\n createVault,\n dispatch,\n fetchProjects,\n needsProjectCreation,\n orgName,\n persistDefaults,\n refetchDefaults,\n effectiveUserId,\n userLoading,\n ]);\n\n const isOrgLoading =\n isAuthenticated &&\n !orgName &&\n (userLoading ||\n contextLoading ||\n settingsLoading ||\n orgsLoading ||\n orgsByUserLoading ||\n Boolean(effectiveUserId));\n\n const isProjectLoading =\n !!orgName &&\n !rawSettingsProjectId &&\n !projectId &&\n (isInitializingProject || projectCreating || settingsLoading);\n\n const isLoading = isOrgLoading || isProjectLoading;\n\n return {\n projectId,\n orgName,\n accountUserId: effectiveUserId ?? null,\n tagId,\n loading: isLoading,\n /** True while org slug is still unknown (Home should wait before syncing route). */\n orgLoading: isOrgLoading,\n errors: { createError, vaultCreateError },\n };\n}\n"],"names":["_a","_b","_c","_d"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePrerequisiteIds.js","sources":["../../src/hooks/usePrerequisiteIds.ts"],"sourcesContent":["import { DEFAULT_PRODUCTION_TAG_ID } from '@adminide-stack/core/lib/constants/defaultIds.js';\nimport { useContextData } from '@adminide-stack/platform-client/lib/hooks/useContextData.js';\nimport {\n orgChangeAction,\n resourceGroupChangeAction,\n} from '@adminide-stack/platform-client/lib/redux/actions/org-action.js';\nimport { isAuthenticatedSelector } from '@adminide-stack/user-auth0-client';\nimport { ConfigurationTarget, ContributionSchemaId } from 'common';\nimport {\n useAccountProfileQuery,\n useCreateVaultMutation,\n useGetProjectsLazyQuery,\n useGetUserOrganizationsQuery,\n useGetUserOrganizationsWithDetailsQuery,\n useQuickCreateProjectForAccountBkMutation,\n useWriteSettingsMutation,\n} from 'common/graphql';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useAccountDefaultSettings } from './useAccountDefaultSettings';\nimport { isYantraChatOrgSlug, pickWorkspaceOrgSlug } from '../features/messaging/yantraChatOrg';\nimport { isUnhydratedCdecodeUri, settingsUriForAccount, toUriInput } from '../utils/cdecodeUri';\n\nconst uuidToObjectId = (uuid: string) => uuid.replace(/-/g, '').substring(0, 24);\n\nconst PROJECT_NAME = 'DEFAULT_YANTRA_PROJECT';\nconst TAG_ID = uuidToObjectId(DEFAULT_PRODUCTION_TAG_ID);\n/** SystemContributionExtensionNames.Account — owns `account.default.*`. */\nconst ACCOUNT_EXTENSION = 'account';\n\n/**\n * DEV ONLY — known working project UUID for local mobile bootstrap when create/list\n * cannot resolve `projectId`. Never use on staging/prod: createSecretApiToken needs a\n * real project that resolves to a Mongo ObjectId (unknown UUID → ObjectId cast 400).\n */\nconst TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nconst ORG_RESOLVE_POLL_MS = 2000;\nconst PROFILE_POLL_MS = 1500;\n\n// ── Module-level project fix (parity with browser) ───────────────────────────\n// Several screens/hooks mount `usePrerequisiteIds` at once. Per-instance refs race\n// and can create multiple orphan projects. Keep a single-flight guard + user id so\n// adopt/create/persist runs once per account session.\n// Resolved project must also be shared — otherwise WebBuilderPrewarm can \"win\" the\n// flight and HomeScreen never sees projectId (submit stuck on \"not ready\").\nlet projectFixInFlight = false;\nlet projectFixUserId: string | null = null;\nlet sharedResolvedProjectId: string | null = null;\nconst sharedProjectListeners = new Set<() => void>();\n\nfunction publishSharedResolvedProjectId(projectUuid: string): void {\n sharedResolvedProjectId = projectUuid;\n sharedProjectListeners.forEach((listener) => listener());\n}\n\nfunction pickDefaultOrgSlug(\n orgs: Array<{ name?: string | null; title?: string | null } | null | undefined> | null | undefined,\n): string | null {\n return pickWorkspaceOrgSlug(orgs);\n}\n\n/**\n * Org + project prerequisites for mobile (parity with browser `usePrerequisiteIds`).\n *\n * Settings use the same `account.default` config as web (`useSettingsLoader` → `useSettings` on mobile).\n * After verify-user, account-level settings (`//accounts/{id}#settings`) and org membership are polled\n * until `organization` is available, then route context is synced on Home.\n *\n * Scenario: org set but no `account.default.project` → adopt an existing project in the org\n * (or create one), persist settings, and bind resourceGroup — same as browser Scenario 2.\n */\nexport function usePrerequisiteIds() {\n const dispatch = useDispatch();\n const isAuthenticated = useSelector(isAuthenticatedSelector);\n\n const { data: contextData, complete: contextComplete } = useContextData();\n const contextLoading = !contextComplete;\n const cdecodeUri = contextData?.cdecodeUri;\n const contextUserId = contextData?.userId ?? null;\n\n const contextResourceUri = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return undefined;\n return toUriInput(cdecodeUri);\n }, [cdecodeUri]);\n\n const {\n data: accountProfileData,\n loading: userLoading,\n refetch: refetchProfile,\n } = useAccountProfileQuery({\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n skip: !isAuthenticated,\n });\n const profileUserId = accountProfileData?.accountProfile?.user?.id ?? null;\n const effectiveUserId = isAuthenticated ? profileUserId || contextUserId : null;\n\n useEffect(() => {\n if (!isAuthenticated || profileUserId) return;\n const timer = setInterval(() => {\n refetchProfile().catch(() => undefined);\n }, PROFILE_POLL_MS);\n return () => clearInterval(timer);\n }, [isAuthenticated, profileUserId, refetchProfile]);\n\n // Step 1 (web): account.default via settings loader — context cdecodeUri when hydrated\n const {\n organization: orgFromContextSettings,\n project: projectFromContextSettings,\n environment: envFromContextSettings,\n loading: contextSettingsLoading,\n refetch: refetchContextSettings,\n } = useAccountDefaultSettings({\n resourceUri: contextResourceUri,\n skip: !isAuthenticated || !contextResourceUri,\n });\n\n const accountResourceUri = useMemo(() => {\n if (!effectiveUserId || orgFromContextSettings) return undefined;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId, orgFromContextSettings]);\n\n // Mobile bootstrap: read account.default from account document before org is on the route\n const {\n organization: orgFromAccountSettings,\n project: projectFromAccountSettings,\n environment: envFromAccountSettings,\n loading: accountSettingsLoading,\n refetch: refetchAccountSettings,\n } = useAccountDefaultSettings({\n resourceUri: accountResourceUri,\n skip: !isAuthenticated || !accountResourceUri,\n });\n\n const {\n data: orgsData,\n loading: orgsLoading,\n refetch: refetchOrgs,\n } = useGetUserOrganizationsWithDetailsQuery({\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const {\n data: orgsByUserData,\n loading: orgsByUserLoading,\n refetch: refetchOrgsByUser,\n } = useGetUserOrganizationsQuery({\n variables: { userId: effectiveUserId ?? undefined },\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const orgFromMembership = useMemo(() => {\n const fromDetails = pickDefaultOrgSlug(orgsData?.getUserOrganizationsWithDetails);\n if (fromDetails) return fromDetails;\n return pickDefaultOrgSlug(orgsByUserData?.getUserOrganizations);\n }, [orgsData, orgsByUserData]);\n\n const orgFromContextPath = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return null;\n const { path } = toUriInput(cdecodeUri);\n const match = path.match(/^\\/([^/]+)\\//);\n const slug = match?.[1]?.trim() || null;\n if (slug && isYantraChatOrgSlug(slug)) return null;\n return slug;\n }, [cdecodeUri]);\n\n const orgName = orgFromContextSettings || orgFromAccountSettings || orgFromMembership || orgFromContextPath || null;\n\n const rawSettingsProjectIdRaw = projectFromContextSettings || projectFromAccountSettings || null;\n // Staging may have persisted the local testing UUID; treat it as unset so bootstrap can mint a real project.\n const rawSettingsProjectId =\n !__DEV__ && rawSettingsProjectIdRaw === TESTING_PROJECT_UUID ? null : rawSettingsProjectIdRaw;\n\n /**\n * Env tag every credential read / vault-secret resolve / system-token mint is scoped by,\n * picked on web in Account > Preferences > Workspace and persisted as\n * `account.default.environment` (parity with the browser hook). Empty — the default, and\n * every account that never picked one — keeps the static root Production tag.\n */\n const tagId = (envFromContextSettings || envFromAccountSettings || '').trim() || TAG_ID;\n\n useEffect(() => {\n if (!isAuthenticated || orgName || !effectiveUserId) return;\n const timer = setInterval(() => {\n refetchContextSettings?.()?.catch(() => undefined);\n refetchAccountSettings?.()?.catch(() => undefined);\n refetchOrgs().catch(() => undefined);\n refetchOrgsByUser().catch(() => undefined);\n }, ORG_RESOLVE_POLL_MS);\n return () => clearInterval(timer);\n }, [\n isAuthenticated,\n orgName,\n effectiveUserId,\n refetchContextSettings,\n refetchAccountSettings,\n refetchOrgs,\n refetchOrgsByUser,\n ]);\n\n const settingsProjectId = rawSettingsProjectId;\n\n const [resolvedProjectId, setResolvedProjectId] = useState<string | null>(() => sharedResolvedProjectId);\n const [isInitializingProject, setIsInitializingProject] = useState(false);\n\n // Cross-instance sync: when another hook wins the project bootstrap, adopt it.\n useEffect(() => {\n const onShared = () => {\n if (sharedResolvedProjectId) setResolvedProjectId(sharedResolvedProjectId);\n };\n sharedProjectListeners.add(onShared);\n onShared();\n return () => {\n sharedProjectListeners.delete(onShared);\n };\n }, []);\n\n // New account session → clear shared fallback so we don't leak another user's project.\n useEffect(() => {\n if (!effectiveUserId) return;\n if (projectFixUserId && projectFixUserId !== effectiveUserId) {\n sharedResolvedProjectId = null;\n projectFixInFlight = false;\n setResolvedProjectId(null);\n }\n }, [effectiveUserId]);\n\n const projectId = settingsProjectId || resolvedProjectId || sharedResolvedProjectId;\n const settingsLoading = contextSettingsLoading || accountSettingsLoading;\n // Wait for settings to settle so we don't create before an existing default loads.\n const needsProjectCreation = !settingsLoading && !!orgName && !rawSettingsProjectId && !projectId;\n\n const [fetchProjects] = useGetProjectsLazyQuery();\n const [createProject, { error: createError, loading: projectCreating }] =\n useQuickCreateProjectForAccountBkMutation();\n const [createVault, { error: vaultCreateError }] = useCreateVaultMutation();\n const [writeSettings] = useWriteSettingsMutation();\n\n const accountSettingsUri = useMemo(() => {\n if (!effectiveUserId) return null;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId]);\n\n const persistDefaults = useCallback(\n async (orgToSet: string, projectUuid: string) => {\n if (!accountSettingsUri) return;\n await writeSettings({\n variables: {\n // The URI scalar's TS type is the vscode URI class, but the wire\n // format is this serializable POJO (same shape toUriInput emits).\n editingUri:\n accountSettingsUri as unknown as import('@vscode-alt/monaco-editor/esm/vs/base/common/uri.js').URI,\n settings: {\n 'account.default.organization': orgToSet,\n 'account.default.project': projectUuid,\n },\n target: ConfigurationTarget.USER,\n schemaId: ContributionSchemaId.Configuration,\n extensionName: ACCOUNT_EXTENSION,\n },\n });\n },\n [accountSettingsUri, writeSettings],\n );\n\n const refetchDefaults = useCallback(async () => {\n await Promise.all([\n refetchContextSettings?.()?.catch(() => undefined) ?? Promise.resolve(),\n refetchAccountSettings?.()?.catch(() => undefined) ?? Promise.resolve(),\n ]);\n }, [refetchContextSettings, refetchAccountSettings]);\n\n // Scenario 2: default org present but no project → adopt existing (or create once),\n // then persist so reload / other mounts do not create orphan projects.\n useEffect(() => {\n if (!needsProjectCreation || !effectiveUserId || userLoading || !orgName) {\n return;\n }\n\n if (projectFixUserId !== effectiveUserId) {\n projectFixUserId = effectiveUserId;\n projectFixInFlight = false;\n sharedResolvedProjectId = null;\n }\n\n if (projectFixInFlight) {\n return;\n }\n\n projectFixInFlight = true;\n setIsInitializingProject(true);\n\n (async () => {\n try {\n const existing = await fetchProjects({ variables: { orgName, limit: 50 } });\n let projectUuid =\n (existing.data?.getProjects?.data || []).find((p) => p?.projectId)?.projectId ?? undefined;\n let newMongoProjectId: string | undefined;\n\n if (!projectUuid) {\n const created = await createProject({\n variables: {\n input: {\n accountId: effectiveUserId,\n projectName: PROJECT_NAME,\n },\n },\n });\n newMongoProjectId = created.data?.quickCreateProjectForAccount?.id ?? undefined;\n if (newMongoProjectId) {\n const after = await fetchProjects({ variables: { orgName, limit: 50 } });\n projectUuid =\n (after.data?.getProjects?.data || []).find((p) => p?.id === newMongoProjectId)?.projectId ??\n // createSecretApiToken accepts Mongo ObjectId directly when no UUID dashes.\n newMongoProjectId;\n await createVault({\n variables: {\n input: {\n orgName,\n projectId: newMongoProjectId,\n },\n },\n }).catch((error) =>\n console.error('[usePrerequisiteIds] Vault creation failed:', error?.message),\n );\n } else {\n console.warn('[usePrerequisiteIds] Project creation returned no id');\n }\n }\n\n if (!projectUuid) {\n if (__DEV__) {\n console.warn(\n `[usePrerequisiteIds] Could not resolve a project UUID — using testing project ${TESTING_PROJECT_UUID}`,\n );\n projectUuid = TESTING_PROJECT_UUID;\n } else {\n console.error(\n '[usePrerequisiteIds] Could not resolve a project UUID — refusing testing fallback outside __DEV__',\n );\n projectFixInFlight = false;\n return;\n }\n }\n\n setResolvedProjectId(projectUuid);\n publishSharedResolvedProjectId(projectUuid);\n await persistDefaults(orgName, projectUuid);\n dispatch(orgChangeAction({ orgName, userId: effectiveUserId }));\n dispatch(resourceGroupChangeAction({ resourceGroup: projectUuid }));\n await refetchDefaults();\n } catch (error) {\n console.error('[usePrerequisiteIds] Project bootstrap failed:', (error as Error)?.message);\n if (__DEV__) {\n console.warn(\n `[usePrerequisiteIds] Falling back to testing project ${TESTING_PROJECT_UUID} after bootstrap error`,\n );\n setResolvedProjectId(TESTING_PROJECT_UUID);\n publishSharedResolvedProjectId(TESTING_PROJECT_UUID);\n try {\n await persistDefaults(orgName, TESTING_PROJECT_UUID);\n dispatch(orgChangeAction({ orgName, userId: effectiveUserId }));\n dispatch(resourceGroupChangeAction({ resourceGroup: TESTING_PROJECT_UUID }));\n await refetchDefaults();\n } catch (persistError) {\n console.error(\n '[usePrerequisiteIds] Testing fallback persist failed:',\n (persistError as Error)?.message,\n );\n projectFixInFlight = false;\n }\n } else {\n projectFixInFlight = false;\n }\n } finally {\n setIsInitializingProject(false);\n }\n })();\n }, [\n createProject,\n createVault,\n dispatch,\n fetchProjects,\n needsProjectCreation,\n orgName,\n persistDefaults,\n refetchDefaults,\n effectiveUserId,\n userLoading,\n ]);\n\n const isOrgLoading =\n isAuthenticated &&\n !orgName &&\n (userLoading ||\n contextLoading ||\n settingsLoading ||\n orgsLoading ||\n orgsByUserLoading ||\n Boolean(effectiveUserId));\n\n const isProjectLoading =\n !!orgName &&\n !rawSettingsProjectId &&\n !projectId &&\n (isInitializingProject || projectCreating || settingsLoading);\n\n const isLoading = isOrgLoading || isProjectLoading;\n\n return {\n projectId,\n orgName,\n accountUserId: effectiveUserId ?? null,\n tagId,\n loading: isLoading,\n /** True while org slug is still unknown (Home should wait before syncing route). */\n orgLoading: isOrgLoading,\n errors: { createError, vaultCreateError },\n };\n}\n"],"names":["_a","_b","_c","_d"],"mappings":"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"}
|
package/lib/routes.json
CHANGED
|
@@ -439,7 +439,7 @@
|
|
|
439
439
|
"name": "NavigationHeader",
|
|
440
440
|
"component": "$.importPaths.navigationHeader",
|
|
441
441
|
"props": {
|
|
442
|
-
"showTitle":
|
|
442
|
+
"showTitle": false,
|
|
443
443
|
"showToggle": false,
|
|
444
444
|
"showFilter": false,
|
|
445
445
|
"isSearchBack": false,
|
|
@@ -456,9 +456,14 @@
|
|
|
456
456
|
},
|
|
457
457
|
"options": {
|
|
458
458
|
"title": "Chats",
|
|
459
|
-
"headerTintColor": "
|
|
459
|
+
"headerTintColor": "#ea580c",
|
|
460
|
+
"headerStyle": {
|
|
461
|
+
"backgroundColor": "#ffffff"
|
|
462
|
+
},
|
|
463
|
+
"headerShadowVisible": false,
|
|
460
464
|
"headerTitleStyle": {
|
|
461
|
-
"fontWeight": "
|
|
465
|
+
"fontWeight": "700",
|
|
466
|
+
"fontSize": 20
|
|
462
467
|
},
|
|
463
468
|
"drawerItemStyle": {
|
|
464
469
|
"display": "none"
|