aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/apis/GoogleAuthenticationManager.tsx98
-rw-r--r--src/client/views/nodes/TaskBox.tsx57
2 files changed, 118 insertions, 37 deletions
diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx
index 1b1d6f734..a93e03e60 100644
--- a/src/client/apis/GoogleAuthenticationManager.tsx
+++ b/src/client/apis/GoogleAuthenticationManager.tsx
@@ -42,46 +42,72 @@ export class GoogleAuthenticationManager extends ObservableReactComponent<object
this.openState && this.resetState(0, 0);
}
- public fetchOrGenerateAccessToken = async (displayIfFound = false) => {
- const response = await Networking.FetchFromServer('/readGoogleAccessToken');
- // if this is an authentication url, activate the UI to register the new access token
- if (new RegExp(AuthenticationUrl).test(response)) {
- this.isOpen = true;
- this.authenticationLink = response;
-
- // GETS STUCK AT THIS PROMISE!!
- return new Promise<string>(resolve => {
- this.disposer?.();
- this.disposer = reaction(
- () => this.authenticationCode,
- async authenticationCode => {
- if (authenticationCode && /\d{1}\/[\w-]{55}/.test(authenticationCode)) {
- resolve(authenticationCode);
- this.disposer?.();
- // const response2 = await Networking.PostToServer('/writeGoogleAccessToken', { authenticationCode });
- // runInAction(() => {
- // this.success = true;
- // this.credentials = response2 as { user_info: { name: string; picture: string }; access_token: string };
- // });
- // resolve((response2 as { access_token: string }).access_token);
- this.resetState();
- }
- }
- );
- });
- }
+ // public fetchOrGenerateAccessToken = async (displayIfFound = false) => {
+ // const response = await Networking.FetchFromServer('/readGoogleAccessToken');
+ // // if this is an authentication url, activate the UI to register the new access token
+
+ // if (new RegExp(AuthenticationUrl).test(response)) {
+ // this.isOpen = true;
+ // this.authenticationLink = response;
- // otherwise, we already have a valid, stored access token and user info
- const response2 = JSON.parse(response) as { user_info: { name: string; picture: string }; access_token: string };
- if (displayIfFound) {
+ // // GETS STUCK AT THIS PROMISE!!
+ // return new Promise<string>(resolve => {
+ // this.disposer?.();
+ // this.disposer = reaction(
+ // () => this.authenticationCode,
+ // async authenticationCode => {
+ // if (authenticationCode && /\d{1}\/[\w-]{55}/.test(authenticationCode)) {
+ // resolve(authenticationCode);
+ // this.disposer?.();
+ // // const response2 = await Networking.PostToServer('/writeGoogleAccessToken', { authenticationCode });
+ // // runInAction(() => {
+ // // this.success = true;
+ // // this.credentials = response2 as { user_info: { name: string; picture: string }; access_token: string };
+ // // });
+ // // resolve((response2 as { access_token: string }).access_token);
+ // this.resetState();
+ // }
+ // }
+ // );
+ // });
+ // }
+
+ // // otherwise, we already have a valid, stored access token and user info
+ // const response2 = JSON.parse(response) as { user_info: { name: string; picture: string }; access_token: string };
+ // if (displayIfFound) {
+ // runInAction(() => {
+ // this.success = true;
+ // this.credentials = response2;
+ // });
+ // this.resetState(-1, -1);
+ // this.isOpen = true;
+ // }
+ // return (response2 as { access_token: string }).access_token;
+ // };
+
+ public fetchOrGenerateAccessToken = async (): Promise<string> => {
+ 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 = response2;
+ this.credentials = parsed;
});
- this.resetState(-1, -1);
- this.isOpen = true;
+
+ return parsed.access_token;
+ } catch (err) {
+ console.warn('Not linked yet or invalid JSON. Redirecting to 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
+ }
+
+ throw new Error('Unable to fetch Google access token.');
}
- return (response2 as { access_token: string }).access_token;
};
resetState = action((visibleForMS: number = 3000, fadesOutInMS: number = 500) => {
@@ -132,7 +158,7 @@ export class GoogleAuthenticationManager extends ObservableReactComponent<object
</button>
) : null}
{this.showPasteTargetState ? <input className={'paste-target'} onChange={action(e => (this.authenticationCode = e.currentTarget.value))} placeholder={prompt} /> : null}
- {this.credentials ? (
+ {this.credentials?.user_info?.picture ? (
<>
<img className={'avatar'} src={this.credentials.user_info.picture} />
<span className={'welcome'}>Welcome to Dash, {this.credentials.user_info.name}</span>
diff --git a/src/client/views/nodes/TaskBox.tsx b/src/client/views/nodes/TaskBox.tsx
index 3990356b9..8855e43c8 100644
--- a/src/client/views/nodes/TaskBox.tsx
+++ b/src/client/views/nodes/TaskBox.tsx
@@ -6,6 +6,7 @@ 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';
@@ -270,7 +271,7 @@ export class TaskBox extends React.Component<TaskBoxProps> {
)}
{/** test button */}
- <button
+ {/* <button
className="task-manager-google"
onClick={async () => {
console.log('GT button clicked');
@@ -301,6 +302,60 @@ export class TaskBox extends React.Component<TaskBoxProps> {
}
}}>
GT
+ </button> */}
+
+ {/* <button
+ className="task-manager-google"
+ onClick={async () => {
+ console.log('GT button clicked');
+ const url = await Networking.FetchFromServer('/readGoogleAccessToken');
+ console.log('πŸ”— Redirecting to Google auth:', url);
+ window.location.href = url; // Redirect user to authenticate
+ }}
+ >
+ GT
+ </button> */}
+
+ <button
+ className="task-manager-google"
+ onClick={async event => {
+ event.preventDefault();
+
+ console.log('GT button clicked');
+ try {
+ const token = await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
+ console.log('Got token', token);
+
+ const response = await fetch('/googleTasks/create', {
+ method: 'POST',
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: `Bearer ${token}`,
+ },
+ body: JSON.stringify({
+ title: taskTitle || 'Untitled Task',
+ notes: taskDesc,
+ due: allDay ? String(doc.$task_dateRange)?.split('|')[0] + 'T23:59:00Z' : (doc.$task_endTime instanceof DateField && doc.$task_endTime.date?.toISOString()) || undefined,
+ status: doc.$task_completed ? 'completed' : 'needsAction',
+ completed: doc.$task_completed ? new Date().toISOString() : undefined,
+ }),
+ });
+
+ const result = await response.json();
+ console.log('Google Task result:', result);
+
+ if (result?.id) {
+ alert('βœ… Task sent to Google Tasks!');
+ } else {
+ alert(`❌ Failed: ${result?.error?.message || 'Unknown error'}`);
+ }
+ } catch (err) {
+ console.error('Fetch error:', err);
+ alert('❌ Task creation failed.');
+ }
+ }}>
+ GT
</button>
</div>
);