-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathauth.js
More file actions
180 lines (163 loc) · 5.51 KB
/
Copy pathauth.js
File metadata and controls
180 lines (163 loc) · 5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Google OAuth 2.0 Authentication for RunTrack using Google Identity Services
// Google OAuth 2.0 Configuration
const CLIENT_ID = '15357168879-t8hrv5a801rbdln2pg2a03ted2dd65o9.apps.googleusercontent.com';
const SCOPES = 'https://www.googleapis.com/auth/fitness.activity.write';
// Module-level variables
let tokenClient = null;
let accessToken = null;
let tokenExpiry = null;
// 1. initGoogleAuth() - initializes the token client
function initGoogleAuth() {
return new Promise((resolve, reject) => {
// Load Google Identity Services library
if (typeof google === 'undefined' || !google.accounts) {
// Load the GIS library if not already loaded
const script = document.createElement('script');
script.src = 'https://accounts.google.com/gsi/client';
script.onload = () => {
initializeTokenClient();
resolve();
};
script.onerror = () => reject(new Error('Failed to load Google Identity Services'));
document.head.appendChild(script);
} else {
initializeTokenClient();
resolve();
}
});
}
function initializeTokenClient() {
try {
tokenClient = google.accounts.oauth2.initTokenClient({
client_id: CLIENT_ID,
scope: SCOPES,
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
accessToken = tokenResponse.access_token;
// Set expiry time (tokens typically expire in 1 hour)
tokenExpiry = Date.now() + (tokenResponse.expires_in * 1000);
console.log('Google OAuth token obtained successfully');
} else {
console.error('Failed to obtain Google OAuth token:', tokenResponse);
accessToken = null;
tokenExpiry = null;
}
},
error_callback: (error) => {
console.error('Google OAuth error:', error);
accessToken = null;
tokenExpiry = null;
}
});
} catch (error) {
console.error('Error initializing Google token client:', error);
tokenClient = null;
}
}
// 2. getAccessToken() - returns Promise with access token
function getAccessToken() {
return new Promise((resolve, reject) => {
// Check if we have a valid token
if (isAuthenticated()) {
resolve(accessToken);
return;
}
// Check if token client is initialized
if (!tokenClient) {
reject(new Error('Google Auth not initialized. Call initGoogleAuth() first.'));
return;
}
// Request new token
try {
tokenClient.requestAccessToken();
// Wait for the token to be obtained (callback will set accessToken)
const checkToken = setInterval(() => {
if (accessToken) {
clearInterval(checkToken);
resolve(accessToken);
} else if (Date.now() - tokenExpiry > 5000) { // Timeout after 5 seconds
clearInterval(checkToken);
reject(new Error('Timeout waiting for Google OAuth token'));
}
}, 100);
} catch (error) {
reject(error);
}
});
}
// 3. isAuthenticated() - returns true if we have a valid non-expired token
function isAuthenticated() {
return accessToken && tokenExpiry && Date.now() < tokenExpiry;
}
// 4. signOut() - revokes the token
function signOut() {
return new Promise((resolve, reject) => {
if (!accessToken) {
resolve(); // Nothing to sign out from
return;
}
// Revoke the token
if (typeof google !== 'undefined' && google.accounts && google.accounts.oauth2) {
google.accounts.oauth2.revoke(accessToken, () => {
console.log('Google OAuth token revoked successfully');
clearToken();
resolve();
});
} else {
// Fallback: just clear the token
clearToken();
resolve();
}
});
}
function clearToken() {
accessToken = null;
tokenExpiry = null;
}
// Utility function to check if token is about to expire (within 5 minutes)
function isTokenExpiringSoon() {
return tokenExpiry && (Date.now() > (tokenExpiry - 5 * 60 * 1000));
}
// Auto-refresh token if it's expiring soon
async function ensureValidToken() {
if (!isAuthenticated() || isTokenExpiringSoon()) {
try {
await getAccessToken();
} catch (error) {
console.warn('Failed to refresh Google OAuth token:', error);
throw error;
}
}
return accessToken;
}
// Export functions for use in other modules
export {
initGoogleAuth,
getAccessToken,
isAuthenticated,
signOut,
ensureValidToken,
isTokenExpiringSoon
};
// For backward compatibility if needed
if (typeof window !== 'undefined') {
window.googleAuth = {
initGoogleAuth,
getAccessToken,
isAuthenticated,
signOut,
ensureValidToken,
isTokenExpiringSoon
};
}
// Also provide CommonJS export for Node.js compatibility
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
initGoogleAuth,
getAccessToken,
isAuthenticated,
signOut,
ensureValidToken,
isTokenExpiringSoon
};
}