@mentra/react 2.1.1 → 2.1.2
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/dist/AuthProvider.d.ts +13 -0
- package/dist/AuthProvider.d.ts.map +1 -0
- package/dist/AuthProvider.js +41 -0
- package/dist/AuthProvider.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/authCore.d.ts +16 -0
- package/dist/lib/authCore.d.ts.map +1 -0
- package/dist/lib/authCore.js +205 -0
- package/dist/lib/authCore.js.map +1 -0
- package/dist/useMentraAuth.d.ts +16 -0
- package/dist/useMentraAuth.d.ts.map +1 -0
- package/dist/useMentraAuth.js +24 -0
- package/dist/useMentraAuth.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { AuthState } from './lib/authCore';
|
|
3
|
+
export interface MentraAuthContextType extends AuthState {
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
error: string | null;
|
|
6
|
+
logout: () => void;
|
|
7
|
+
isAuthenticated: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const MentraAuthContext: React.Context<MentraAuthContextType | undefined>;
|
|
10
|
+
export declare const MentraAuthProvider: ({ children }: {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=AuthProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAsC,SAAS,EAAe,MAAM,OAAO,CAAC;AAC1F,OAAO,EAAmC,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE5E,MAAM,WAAW,qBAAsB,SAAQ,SAAS;IACtD,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,iBAAiB,kDAA8D,CAAC;AAE7F,eAAO,MAAM,kBAAkB,GAAI,cAAc;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,4CAyCvE,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// react-sdk/src/AuthProvider.tsx
|
|
3
|
+
import { createContext, useState, useEffect, useCallback } from 'react';
|
|
4
|
+
import { initializeAuth, clearStoredAuth } from './lib/authCore';
|
|
5
|
+
export const MentraAuthContext = createContext(undefined);
|
|
6
|
+
export const MentraAuthProvider = ({ children }) => {
|
|
7
|
+
const [userId, setUserId] = useState(null);
|
|
8
|
+
const [frontendToken, setFrontendToken] = useState(null);
|
|
9
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
10
|
+
const [error, setError] = useState(null);
|
|
11
|
+
const loadAuth = useCallback(async () => {
|
|
12
|
+
setIsLoading(true);
|
|
13
|
+
setError(null);
|
|
14
|
+
try {
|
|
15
|
+
const auth = await initializeAuth();
|
|
16
|
+
setUserId(auth.userId);
|
|
17
|
+
setFrontendToken(auth.frontendToken);
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
console.error("MentraOS Auth Initialization Error:", e);
|
|
21
|
+
setError(e.message || 'Unknown authentication error');
|
|
22
|
+
clearStoredAuth(); // Clear any potentially bad stored state
|
|
23
|
+
setUserId(null);
|
|
24
|
+
setFrontendToken(null);
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
setIsLoading(false);
|
|
28
|
+
}
|
|
29
|
+
}, []);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
loadAuth();
|
|
32
|
+
}, [loadAuth]);
|
|
33
|
+
const logout = useCallback(() => {
|
|
34
|
+
clearStoredAuth();
|
|
35
|
+
setUserId(null);
|
|
36
|
+
setFrontendToken(null);
|
|
37
|
+
}, []);
|
|
38
|
+
const isAuthenticated = !!userId && !!frontendToken;
|
|
39
|
+
return (_jsx(MentraAuthContext.Provider, { value: { userId, frontendToken, isLoading, error, logout, isAuthenticated }, children: children }));
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=AuthProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthProvider.js","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":";AAAA,iCAAiC;AACjC,OAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAa,WAAW,EAAE,MAAM,OAAO,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,eAAe,EAAa,MAAM,gBAAgB,CAAC;AAS5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAoC,SAAS,CAAC,CAAC;AAE7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAAE,QAAQ,EAA2B,EAAE,EAAE;IAC1E,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACtC,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;YACpC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,CAAC,CAAC,CAAC;YACxD,QAAQ,CAAE,CAAW,CAAC,OAAO,IAAI,8BAA8B,CAAC,CAAC;YACjE,eAAe,EAAE,CAAC,CAAC,yCAAyC;YAC5D,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,EAAE,CAAC;IACb,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9B,eAAe,EAAE,CAAC;QAClB,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,aAAa,CAAC;IAEpD,OAAO,CACL,KAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,YACpG,QAAQ,GACkB,CAC9B,CAAC;AACJ,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface AuthState {
|
|
2
|
+
userId: string | null;
|
|
3
|
+
frontendToken: string | null;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Initializes authentication by checking for tokens in URL parameters or localStorage
|
|
7
|
+
* Priority:
|
|
8
|
+
* 1. aos_signed_user_token in URL -> verify client-side (JWT)
|
|
9
|
+
* 2. aos_temp_token in URL -> exchange via backend
|
|
10
|
+
* 3. localStorage fallback
|
|
11
|
+
* @returns Promise that resolves to the current authentication state
|
|
12
|
+
*/
|
|
13
|
+
export declare function initializeAuth(): Promise<AuthState>;
|
|
14
|
+
export declare function getStoredAuth(): AuthState;
|
|
15
|
+
export declare function clearStoredAuth(): void;
|
|
16
|
+
//# sourceMappingURL=authCore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authCore.d.ts","sourceRoot":"","sources":["../../src/lib/authCore.ts"],"names":[],"mappings":"AAkCA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAuGD;;;;;;;GAOG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,SAAS,CAAC,CA4FzD;AAED,wBAAgB,aAAa,IAAI,SAAS,CAIzC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAGtC"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// react-sdk/src/lib/authCore.ts
|
|
2
|
+
import { KEYUTIL, KJUR } from "jsrsasign"; // Assuming jsrsasign is available
|
|
3
|
+
// This should be the MentraOS Cloud's public key for verifying aos_signed_user_token
|
|
4
|
+
const userTokenPublicKeyPEM = `-----BEGIN PUBLIC KEY-----
|
|
5
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Yt2RtNOdeKQxWMY0c84
|
|
6
|
+
ADpY1Jy58YWZhaEgP2A5tBwFUKgy/TH9gQLWZjQ3dQ/6XXO8qq0kluoYFqM7ZDRF
|
|
7
|
+
zJ0E4Yi0WQncioLRcCx4q8pDmqY9vPKgv6PruJdFWca0l0s3gZ3BqSeWum/C23xK
|
|
8
|
+
FPHPwi8gvRdc6ALrkcHeciM+7NykU8c0EY8PSitNL+Tchti95kGu+j6APr5vNewi
|
|
9
|
+
zRpQGOdqaLWe+ahHmtj6KtUZjm8o6lan4f/o08C6litizguZXuw2Nn/Kd9fFI1xF
|
|
10
|
+
IVNJYMy9jgGaOi71+LpGw+vIpwAawp/7IvULDppvY3DdX5nt05P1+jvVJXPxMKzD
|
|
11
|
+
TQIDAQAB
|
|
12
|
+
-----END PUBLIC KEY-----`;
|
|
13
|
+
const USER_ID_KEY = "mentraos_userId";
|
|
14
|
+
const FRONTEND_TOKEN_KEY = "mentraos_frontendToken";
|
|
15
|
+
/**
|
|
16
|
+
* Verifies and parses a signed user token using the MentraOS Cloud public key
|
|
17
|
+
* @param signedUserToken - The JWT token to verify and parse
|
|
18
|
+
* @returns Promise that resolves to the parsed payload or null if invalid
|
|
19
|
+
*/
|
|
20
|
+
async function verifyAndParseToken(signedUserToken) {
|
|
21
|
+
try {
|
|
22
|
+
const publicKeyObj = KEYUTIL.getKey(userTokenPublicKeyPEM);
|
|
23
|
+
// verifyJWT will check signature, nbf, exp.
|
|
24
|
+
// It will also check 'iss' if provided in the options.
|
|
25
|
+
const isValid = KJUR.jws.JWS.verifyJWT(signedUserToken, publicKeyObj, {
|
|
26
|
+
alg: ["RS256"], // Specify expected algorithms
|
|
27
|
+
iss: ["https://prod.augmentos.cloud"], // Specify expected issuer
|
|
28
|
+
// jsrsasign's verifyJWT checks 'nbf' and 'exp' by default.
|
|
29
|
+
// Grace period for clock skew
|
|
30
|
+
gracePeriod: 120, // 2 minutes in seconds
|
|
31
|
+
});
|
|
32
|
+
if (!isValid) {
|
|
33
|
+
// Parse the token to get header and payload for debugging
|
|
34
|
+
const parsedJWT = KJUR.jws.JWS.parse(signedUserToken);
|
|
35
|
+
if (parsedJWT) {
|
|
36
|
+
console.warn("Token validation failed. Header:", parsedJWT.headerObj, "Payload:", parsedJWT.payloadObj);
|
|
37
|
+
// Check expiration manually for more detailed logging if needed
|
|
38
|
+
const payload = parsedJWT.payloadObj;
|
|
39
|
+
if (payload && payload.exp) {
|
|
40
|
+
const now = KJUR.jws.IntDate.get("now");
|
|
41
|
+
if (payload.exp < now - 120) {
|
|
42
|
+
// Check with grace period
|
|
43
|
+
console.warn(`Token expired at ${new Date(payload.exp * 1000).toISOString()}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const parsedJWT = KJUR.jws.JWS.parse(signedUserToken);
|
|
50
|
+
if (!parsedJWT || !parsedJWT.payloadObj) {
|
|
51
|
+
console.error("Failed to parse JWT payload.");
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const payload = parsedJWT.payloadObj;
|
|
55
|
+
if (!payload.sub || !payload.frontendToken) {
|
|
56
|
+
console.error("Parsed payload missing sub (userId) or frontendToken.");
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return payload;
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
console.error("[verifyAndParseToken] Error verifying token:", e);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Exchanges a temp token with the backend to get session cookie
|
|
68
|
+
* @param tempToken - The aos_temp_token from URL
|
|
69
|
+
* @param signedUserToken - Optional aos_signed_user_token (JWT) for fallback auth
|
|
70
|
+
* @returns Promise that resolves to auth state or null on failure
|
|
71
|
+
*/
|
|
72
|
+
async function exchangeTempToken(tempToken, signedUserToken) {
|
|
73
|
+
try {
|
|
74
|
+
// Build the exchange URL with all necessary params from the current URL
|
|
75
|
+
const params = new URLSearchParams(window.location.search);
|
|
76
|
+
const cloudApiUrl = params.get("cloudApiUrl");
|
|
77
|
+
const cloudApiUrlChecksum = params.get("cloudApiUrlChecksum");
|
|
78
|
+
const exchangeParams = new URLSearchParams({ aos_temp_token: tempToken });
|
|
79
|
+
// IMPORTANT: Also send the signed user token so backend can set cookie from JWT
|
|
80
|
+
if (signedUserToken)
|
|
81
|
+
exchangeParams.set("aos_signed_user_token", signedUserToken);
|
|
82
|
+
if (cloudApiUrl)
|
|
83
|
+
exchangeParams.set("cloudApiUrl", cloudApiUrl);
|
|
84
|
+
if (cloudApiUrlChecksum)
|
|
85
|
+
exchangeParams.set("cloudApiUrlChecksum", cloudApiUrlChecksum);
|
|
86
|
+
console.log("[exchangeTempToken] Calling /api/mentra/auth/init with params:", Array.from(exchangeParams.keys()));
|
|
87
|
+
const response = await fetch(`/api/mentra/auth/init?${exchangeParams.toString()}`, {
|
|
88
|
+
method: "GET",
|
|
89
|
+
credentials: "include", // Include cookies to receive Set-Cookie
|
|
90
|
+
});
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
console.error("[exchangeTempToken] Backend returned error:", response.status);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const data = await response.json();
|
|
96
|
+
console.log("[exchangeTempToken] Response:", { success: data.success, userId: data.userId });
|
|
97
|
+
if (data.success && data.userId && data.frontendToken) {
|
|
98
|
+
return { userId: data.userId, frontendToken: data.frontendToken };
|
|
99
|
+
}
|
|
100
|
+
console.error("[exchangeTempToken] Invalid response:", data);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error("[exchangeTempToken] Network error:", error);
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Initializes authentication by checking for tokens in URL parameters or localStorage
|
|
110
|
+
* Priority:
|
|
111
|
+
* 1. aos_signed_user_token in URL -> verify client-side (JWT)
|
|
112
|
+
* 2. aos_temp_token in URL -> exchange via backend
|
|
113
|
+
* 3. localStorage fallback
|
|
114
|
+
* @returns Promise that resolves to the current authentication state
|
|
115
|
+
*/
|
|
116
|
+
export async function initializeAuth() {
|
|
117
|
+
console.log("[initializeAuth] 🔍 Starting auth initialization...");
|
|
118
|
+
const params = new URLSearchParams(window.location.search);
|
|
119
|
+
console.log("[initializeAuth] 📋 URL params:", {
|
|
120
|
+
hasSignedUserToken: params.has("aos_signed_user_token"),
|
|
121
|
+
hasTempToken: params.has("aos_temp_token"),
|
|
122
|
+
allParams: Array.from(params.keys()),
|
|
123
|
+
});
|
|
124
|
+
// Priority 1: Check for signed user token (JWT) in URL
|
|
125
|
+
const signedUserToken = params.get("aos_signed_user_token");
|
|
126
|
+
if (signedUserToken) {
|
|
127
|
+
console.log("[initializeAuth] ✅ Found aos_signed_user_token, verifying...");
|
|
128
|
+
const payload = await verifyAndParseToken(signedUserToken); // Renamed from userId to payload for clarity
|
|
129
|
+
if (payload) {
|
|
130
|
+
console.log("[initializeAuth] ✅ JWT verified successfully for user:", payload.sub);
|
|
131
|
+
// If we also have a temp token, exchange it for session cookie
|
|
132
|
+
// Also pass the signedUserToken so backend can use it if temp token fails
|
|
133
|
+
const tempToken = params.get("aos_temp_token");
|
|
134
|
+
if (tempToken) {
|
|
135
|
+
console.log("[initializeAuth] 🔄 Also found aos_temp_token, exchanging for session...");
|
|
136
|
+
await exchangeTempToken(tempToken, signedUserToken); // Pass JWT for fallback
|
|
137
|
+
}
|
|
138
|
+
// Extract frontendToken from JWT payload
|
|
139
|
+
// The payload is already parsed by verifyAndParseToken, so we can use it directly
|
|
140
|
+
const frontendToken = payload.frontendToken;
|
|
141
|
+
const userId = payload.sub; // Get userId from payload
|
|
142
|
+
if (frontendToken && userId) {
|
|
143
|
+
console.log("[initializeAuth] 💾 Storing tokens and cleaning URL...");
|
|
144
|
+
localStorage.setItem("mentra_user_id", userId);
|
|
145
|
+
localStorage.setItem("mentra_frontend_token", frontendToken);
|
|
146
|
+
// Clean URL
|
|
147
|
+
params.delete("aos_signed_user_token");
|
|
148
|
+
params.delete("aos_temp_token"); // Also delete temp token if it was present and handled
|
|
149
|
+
params.delete("cloudApiUrl"); // Also delete cloudApiUrl if it was present
|
|
150
|
+
params.delete("cloudApiUrlChecksum"); // Also delete cloudApiUrlChecksum if it was present
|
|
151
|
+
const newSearch = params.toString();
|
|
152
|
+
const newUrl = newSearch ? `${window.location.pathname}?${newSearch}` : window.location.pathname;
|
|
153
|
+
window.history.replaceState({}, "", newUrl);
|
|
154
|
+
console.log("[initializeAuth] ✅ Auth complete via signed user token");
|
|
155
|
+
return { userId, frontendToken };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
console.warn("[initializeAuth] ⚠️ JWT verification failed");
|
|
159
|
+
// If verification failed, clear any stored auth and return null state
|
|
160
|
+
clearStoredAuth();
|
|
161
|
+
return { userId: null, frontendToken: null };
|
|
162
|
+
}
|
|
163
|
+
// Priority 2: Check for temp token (needs backend exchange)
|
|
164
|
+
const tempToken = params.get("aos_temp_token");
|
|
165
|
+
if (tempToken) {
|
|
166
|
+
console.log("[initializeAuth] 🔄 Found aos_temp_token, exchanging with backend...");
|
|
167
|
+
const auth = await exchangeTempToken(tempToken);
|
|
168
|
+
if (auth) {
|
|
169
|
+
console.log("[initializeAuth] ✅ Temp token exchange successful for user:", auth.userId);
|
|
170
|
+
localStorage.setItem("mentra_user_id", auth.userId);
|
|
171
|
+
localStorage.setItem("mentra_frontend_token", auth.frontendToken);
|
|
172
|
+
// Clean URL
|
|
173
|
+
params.delete("aos_temp_token");
|
|
174
|
+
params.delete("cloudApiUrl"); // Also delete cloudApiUrl if it was present
|
|
175
|
+
params.delete("cloudApiUrlChecksum"); // Also delete cloudApiUrlChecksum if it was present
|
|
176
|
+
const newSearch = params.toString();
|
|
177
|
+
const newUrl = newSearch ? `${window.location.pathname}?${newSearch}` : window.location.pathname;
|
|
178
|
+
window.history.replaceState({}, "", newUrl);
|
|
179
|
+
console.log("[initializeAuth] ✅ Auth complete via temp token");
|
|
180
|
+
return auth;
|
|
181
|
+
}
|
|
182
|
+
console.warn("[initializeAuth] ⚠️ Temp token exchange failed");
|
|
183
|
+
// If exchange failed, clear any stored auth and return null state
|
|
184
|
+
clearStoredAuth();
|
|
185
|
+
return { userId: null, frontendToken: null };
|
|
186
|
+
}
|
|
187
|
+
// Priority 3: Try to load from localStorage
|
|
188
|
+
console.log("[initializeAuth] 📦 Checking localStorage...");
|
|
189
|
+
const storedUserId = localStorage.getItem("mentra_user_id");
|
|
190
|
+
const storedFrontendToken = localStorage.getItem("mentra_frontend_token");
|
|
191
|
+
if (storedUserId && storedFrontendToken) {
|
|
192
|
+
return { userId: storedUserId, frontendToken: storedFrontendToken };
|
|
193
|
+
}
|
|
194
|
+
return { userId: null, frontendToken: null };
|
|
195
|
+
}
|
|
196
|
+
export function getStoredAuth() {
|
|
197
|
+
const userId = localStorage.getItem(USER_ID_KEY);
|
|
198
|
+
const frontendToken = localStorage.getItem(FRONTEND_TOKEN_KEY);
|
|
199
|
+
return { userId, frontendToken };
|
|
200
|
+
}
|
|
201
|
+
export function clearStoredAuth() {
|
|
202
|
+
localStorage.removeItem(USER_ID_KEY);
|
|
203
|
+
localStorage.removeItem(FRONTEND_TOKEN_KEY);
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=authCore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authCore.js","sourceRoot":"","sources":["../../src/lib/authCore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MentraAuthContextType } from './AuthProvider';
|
|
2
|
+
/**
|
|
3
|
+
* Custom hook to access the MentraOS authentication context.
|
|
4
|
+
*
|
|
5
|
+
* @returns {MentraAuthContextType} The authentication context containing user state,
|
|
6
|
+
* loading status, error information, and authentication methods.
|
|
7
|
+
*
|
|
8
|
+
* @throws {Error} When used outside of an MentraAuthProvider component.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* const { userId, isAuthenticated, logout, isLoading } = UseMentraAuth();
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare const useMentraAuth: () => MentraAuthContextType;
|
|
16
|
+
//# sourceMappingURL=useMentraAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMentraAuth.d.ts","sourceRoot":"","sources":["../src/useMentraAuth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE1E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,QAAO,qBAMhC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// react-sdk/src/UseMentraAuth.ts
|
|
2
|
+
import { useContext } from 'react';
|
|
3
|
+
import { MentraAuthContext } from './AuthProvider';
|
|
4
|
+
/**
|
|
5
|
+
* Custom hook to access the MentraOS authentication context.
|
|
6
|
+
*
|
|
7
|
+
* @returns {MentraAuthContextType} The authentication context containing user state,
|
|
8
|
+
* loading status, error information, and authentication methods.
|
|
9
|
+
*
|
|
10
|
+
* @throws {Error} When used outside of an MentraAuthProvider component.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const { userId, isAuthenticated, logout, isLoading } = UseMentraAuth();
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export const useMentraAuth = () => {
|
|
18
|
+
const context = useContext(MentraAuthContext);
|
|
19
|
+
if (context === undefined) {
|
|
20
|
+
throw new Error('UseMentraAuth must be used within an MentraAuthProvider');
|
|
21
|
+
}
|
|
22
|
+
return context;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=useMentraAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMentraAuth.js","sourceRoot":"","sources":["../src/useMentraAuth.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAyB,MAAM,gBAAgB,CAAC;AAE1E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAA0B,EAAE;IACvD,MAAM,OAAO,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAC9C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
|
package/package.json
CHANGED