aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSkitty1238 <157652284+Skitty1238@users.noreply.github.com>2025-06-04 22:30:11 -0400
committerSkitty1238 <157652284+Skitty1238@users.noreply.github.com>2025-06-04 22:30:11 -0400
commit745784b36e0f6fd2557ffe0d32cf11051627b148 (patch)
treeafb4a23fdb801660b0017c6faefe50ac9e7a6531 /src
parenteb9c93a635191ef9ec842592c4a85262811cf108 (diff)
parent488451f04d42642f11975e9532542a78622b16ef (diff)
Merge branch 'task_nodes_aarav' of https://github.com/brown-dash/Dash-Web into task_nodes_aarav
Diffstat (limited to 'src')
-rw-r--r--src/client/apis/GoogleAuthenticationManager.tsx29
-rw-r--r--src/client/util/SettingsManager.tsx2
-rw-r--r--src/client/views/nodes/TaskBox.tsx1
-rw-r--r--src/server/ApiManagers/GeneralGoogleManager.ts56
-rw-r--r--src/server/apis/google/GoogleApiServerUtils.ts28
-rw-r--r--src/server/apis/google/google_project_credentials.json8
-rw-r--r--src/server/authentication/DashUserModel.ts6
7 files changed, 41 insertions, 89 deletions
diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx
index a93e03e60..70e1ccc05 100644
--- a/src/client/apis/GoogleAuthenticationManager.tsx
+++ b/src/client/apis/GoogleAuthenticationManager.tsx
@@ -1,4 +1,4 @@
-import { action, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { action, IReactionDisposer, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Opt } from '../../fields/Doc';
@@ -8,7 +8,6 @@ import { MainViewModal } from '../views/MainViewModal';
import './GoogleAuthenticationManager.scss';
import { ObservableReactComponent } from '../views/ObservableReactComponent';
-const AuthenticationUrl = 'https://accounts.google.com/o/oauth2/v2/auth';
const prompt = 'Paste authorization code here...';
@observer
@@ -85,27 +84,29 @@ export class GoogleAuthenticationManager extends ObservableReactComponent<object
// return (response2 as { access_token: string }).access_token;
// };
- public fetchOrGenerateAccessToken = async (): Promise<string> => {
+ public fetchOrGenerateAccessToken = async (): Promise<string | undefined> => {
const response = await Networking.FetchFromServer('/readGoogleAccessToken');
-
+
// This will return a JSON object with { access_token, user_info } if already linked
try {
const parsed = JSON.parse(response) as { access_token: string; user_info: { name: string; picture: string } };
-
+
runInAction(() => {
this.success = true;
this.credentials = parsed;
});
-
+
return parsed.access_token;
- } catch (err) {
- console.warn('Not linked yet or invalid JSON. Redirecting to auth...');
+ } catch {
+ console.warn('Not linked yet or invalid JSON. open auth...');
// This is an auth URL — redirect the user to /refreshGoogle
if (typeof response === 'string' && response.startsWith('http')) {
- window.location.href = response;
- return ''; // Won’t be used — this page will reload anyway
+ if (window.confirm('Authorize Dash to access your Google tasks?')) {
+ window.open(response)?.focus();
+ return undefined;
+ }
}
-
+
throw new Error('Unable to fetch Google access token.');
}
};
@@ -182,11 +183,7 @@ export class GoogleAuthenticationManager extends ObservableReactComponent<object
}
render() {
- return (
- <div className="hell">
- <MainViewModal isDisplayed={this.openState} interactive={true} contents={this.renderPrompt} dialogueBoxStyle={this.dialogueBoxStyle} overlayStyle={{ zIndex: 1001 }} closeOnExternalClick={action(() => (this.isOpen = false))} />
- </div>
- );
+ return <MainViewModal isDisplayed={this.openState} interactive={true} contents={this.renderPrompt} dialogueBoxStyle={this.dialogueBoxStyle} overlayStyle={{ zIndex: 1001 }} closeOnExternalClick={action(() => (this.isOpen = false))} />;
}
}
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 9e79fd870..f54dea90c 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -40,7 +40,7 @@ export class SettingsManager extends React.Component<object> {
@observable private _activeTab = 'Accounts';
@observable private _isOpen = false;
- private googleAuthorize = action(() => GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true));
+ private googleAuthorize = action(() => GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken());
public closeMgr = action(() => {
this._isOpen = false;
diff --git a/src/client/views/nodes/TaskBox.tsx b/src/client/views/nodes/TaskBox.tsx
index 0d4fb622b..e755c6fe3 100644
--- a/src/client/views/nodes/TaskBox.tsx
+++ b/src/client/views/nodes/TaskBox.tsx
@@ -6,7 +6,6 @@ import { DocumentType } from '../../documents/DocumentTypes';
import { FieldView } from './FieldView';
import { DateField } from '../../../fields/DateField';
import { Doc } from '../../../fields/Doc';
-import { Networking } from '../../Network';
import './TaskBox.scss';
import { GoogleAuthenticationManager } from '../../apis/GoogleAuthenticationManager';
diff --git a/src/server/ApiManagers/GeneralGoogleManager.ts b/src/server/ApiManagers/GeneralGoogleManager.ts
index 25589ccb5..7581eec13 100644
--- a/src/server/ApiManagers/GeneralGoogleManager.ts
+++ b/src/server/ApiManagers/GeneralGoogleManager.ts
@@ -1,5 +1,5 @@
import ApiManager, { Registration } from './ApiManager';
-import { Method, _success } from '../RouteManager';
+import { Method } from '../RouteManager';
import { GoogleApiServerUtils } from '../apis/google/GoogleApiServerUtils';
import RouteSubscriber from '../RouteSubscriber';
import { Database } from '../database';
@@ -72,19 +72,19 @@ export default class GeneralGoogleManager extends ApiManager {
secureHandler: async ({ req, res, user }) => {
try {
const auth = await GoogleApiServerUtils.retrieveOAuthClient(user);
-
+
if (!auth) {
return res.status(401).send('Google credentials missing or invalid.');
}
-
+
const tasks = google.tasks({ version: 'v1', auth });
-
+
const { title, notes, due, status, completed } = req.body;
const result = await tasks.tasks.insert({
tasklist: '@default',
- requestBody: { title, notes, due, status, completed},
+ requestBody: { title, notes, due, status, completed },
});
-
+
res.status(200).send(result.data);
} catch (err) {
console.error('Google Tasks error:', err);
@@ -96,40 +96,16 @@ export default class GeneralGoogleManager extends ApiManager {
register({
method: Method.GET,
subscription: '/refreshGoogle',
- secureHandler: async ({ user, req, res }) => {
- const code = req.query.code as string;
- console.log('/refreshGoogle hit with code:', code);
-
- try {
- const enriched = await GoogleApiServerUtils.processNewUser(user.id, code);
-
- if (enriched.refresh_token) {
- console.log('Enriched credentials:', enriched);
-
- if (enriched.refresh_token) {
- user.googleToken = enriched.refresh_token;
- await user.save();
- console.log('Saved refresh token to user model');
- } else {
- console.warn('No refresh token returned');
- }
- }
-
- // await user.save();
- // _success(res, 'Google account successfully linked!');
- res.redirect('/home');
-
- } catch (err) {
- console.error('Failed to process Google code:', err);
- res.status(500).send('Error linking Google account');
- }
-
- // const response2 = await Networking.PostToServer('/writeGoogleAccessToken', { authenticationCode });
- // runInAction(() => {
- // this.success = true;
- // this.credentials = response2 as { user_info: { name: string; picture: string }; access_token: string };
- // });
- },
+ secureHandler: async ({ user, req, res }) =>
+ new Promise<void>(resolve =>
+ GoogleApiServerUtils.processNewUser(user.id, req.query.code as string)
+ .then(() => res.status(200).send('Google account linked successfully!'))
+ .catch(err => {
+ console.error('Failed to process Google code:', err);
+ res.status(500).send('Error linking Google account');
+ })
+ .finally(resolve)
+ ),
});
}
}
diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts
index 56bc79119..24905896d 100644
--- a/src/server/apis/google/GoogleApiServerUtils.ts
+++ b/src/server/apis/google/GoogleApiServerUtils.ts
@@ -121,8 +121,7 @@ export namespace GoogleApiServerUtils {
* @returns the relevant 'googleapis' wrapper, if any
*/
export async function GetEndpoint(sector: string, user: DashUserModel): Promise<Endpoint | void> {
- if (!user.googleToken) await retrieveOAuthClient(user);
- const auth = user.googleToken; // await retrieveOAuthClient(user);
+ const auth = await retrieveOAuthClient(user);
if (!auth) {
return;
}
@@ -184,21 +183,7 @@ export namespace GoogleApiServerUtils {
* @returns the newly generated url to the authentication landing page
*/
export function generateAuthenticationUrl(): string {
- const oauth2Client = new google.auth.OAuth2(
- '838617994486-a28072lirm8uk8cm78t7ic4krp0rgkgv.apps.googleusercontent.com',
- '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',
- 'http://localhost:1050/refreshGoogle' // Ensure this matches the redirect URI in Google Cloud Console
- );
-
- return oauth2Client.generateAuthUrl({
- access_type: 'offline',
- scope: [
- 'https://www.googleapis.com/auth/tasks',
- 'openid',
- 'profile'
- ],
- prompt: 'consent', // This ensures we get a refresh token
- });
+ return worker.generateAuthUrl({ scope, access_type: 'offline', prompt: 'consent' });
}
/**
@@ -220,12 +205,12 @@ export namespace GoogleApiServerUtils {
*/
export async function processNewUser(userId: string, authenticationCode: string): Promise<EnrichedCredentials> {
const credentials = await new Promise<Credentials>((resolve, reject) => {
- worker.getToken(authenticationCode, (err, credentials) => {
- if (err || !credentials) {
+ worker.getToken(authenticationCode, (err, creds) => {
+ if (err || !creds) {
reject(err);
return;
}
- resolve(credentials);
+ resolve(creds);
});
});
const enriched = injectUserInfo(credentials);
@@ -312,7 +297,7 @@ export namespace GoogleApiServerUtils {
const headerParameters = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } };
const { client_id, client_secret } = GoogleCredentialsLoader.ProjectCredentials;
const params = new URLSearchParams({
- refresh_token: credentials.refresh_token!, // AARAV use user.googleToken
+ refresh_token: credentials.refresh_token!,
client_id,
client_secret,
grant_type: 'refresh_token',
@@ -321,6 +306,7 @@ export namespace GoogleApiServerUtils {
const { access_token, expires_in } = await new Promise<{ access_token: string; expires_in: number }>(resolve => {
request.post(url, headerParameters).then(response => resolve(JSON.parse(response)));
});
+
// expires_in is in seconds, but we're building the new expiry date in milliseconds
const expiry_date = new Date().getTime() + expires_in * 1000;
await Database.Auxiliary.GoogleAccessToken.Update(user.id, access_token, expiry_date);
diff --git a/src/server/apis/google/google_project_credentials.json b/src/server/apis/google/google_project_credentials.json
index 010f9a626..8abc13b80 100644
--- a/src/server/apis/google/google_project_credentials.json
+++ b/src/server/apis/google/google_project_credentials.json
@@ -1,11 +1,11 @@
{
"installed": {
- "client_id": "838617994486-a28072lirm8uk8cm78t7ic4krp0rgkgv.apps.googleusercontent.com",
- "project_id": "gtasks-test-dash",
+ "client_id": "740987818053-dtflji3hfkn5r9t8ad6jb8740pls8moh.apps.googleusercontent.com",
+ "project_id": "dash-web-461920",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
- "client_secret": "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",
+ "client_secret": "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",
"redirect_uris": ["http://localhost:1050/refreshGoogle"]
}
-} \ No newline at end of file
+}
diff --git a/src/server/authentication/DashUserModel.ts b/src/server/authentication/DashUserModel.ts
index 4397e2bd4..debeef60c 100644
--- a/src/server/authentication/DashUserModel.ts
+++ b/src/server/authentication/DashUserModel.ts
@@ -9,14 +9,9 @@ export type DashUserModel = mongoose.Document & {
passwordResetToken?: string;
passwordResetExpires?: Date;
-
- // AARAV ADD
- googleToken?: string;
-
dropboxRefresh?: string;
dropboxToken?: string;
-
userDocumentId: string;
sharingDocumentId: string;
linkDatabaseId: string;
@@ -45,7 +40,6 @@ const userSchema = new mongoose.Schema(
passwordResetToken: String,
passwordResetExpires: Date,
- googleToken: String,
dropboxRefresh: String,
dropboxToken: String,
userDocumentId: String, // id that identifies a document which hosts all of a user's account data