aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-01-15 13:03:59 -0500
committerbobzel <zzzman@gmail.com>2025-01-15 13:03:59 -0500
commit205fdacf9807be2691e13e1d9d04d6b98620391a (patch)
treea4830b41b8adc3a3bdf9f34773f437ed3e526eea /src/server
parent12f5a435ee6476e2e07ded0c9cdd597c70ca8af0 (diff)
fixed so that users are sentt to dropbox to authorized uploads once, and then a refresh token is used afterwards. fixed up some collection views to work better with the tagsView. fixed grid view to show entire image. tweaked notetaking view to work better with tags, but it's incomplete.
Diffstat (limited to 'src/server')
-rw-r--r--src/server/ApiManagers/FireflyManager.ts94
-rw-r--r--src/server/authentication/DashUserModel.ts5
2 files changed, 94 insertions, 5 deletions
diff --git a/src/server/ApiManagers/FireflyManager.ts b/src/server/ApiManagers/FireflyManager.ts
index a1f8fab8d..6039f5675 100644
--- a/src/server/ApiManagers/FireflyManager.ts
+++ b/src/server/ApiManagers/FireflyManager.ts
@@ -1,7 +1,9 @@
+import axios from 'axios';
import { Dropbox } from 'dropbox';
import * as fs from 'fs';
import * as multipart from 'parse-multipart-data';
import * as path from 'path';
+import { DashUserModel } from '../authentication/DashUserModel';
import { DashUploadUtils } from '../DashUploadUtils';
import { _error, _invalid, _success, Method } from '../RouteManager';
import { Directory, filesDirectory } from '../SocketData';
@@ -55,7 +57,7 @@ export default class FireflyManager extends ApiManager {
)
);
- uploadImageToDropbox = (fileUrl: string, dbx = new Dropbox({ accessToken: process.env.DROPBOX_TOKEN })) =>
+ uploadImageToDropbox = (fileUrl: string, user: DashUserModel | undefined, dbx = new Dropbox({ accessToken: user?.dropboxToken || '' })) =>
new Promise<string | Error>((res, rej) =>
fs.readFile(path.join(filesDirectory, `${Directory.images}/${path.basename(fileUrl)}`), undefined, (err, contents) => {
if (err) {
@@ -69,8 +71,32 @@ export default class FireflyManager extends ApiManager {
.catch(e => res(new Error(e.toString())));
})
.catch(e => {
- console.log('Dropbox error:', e);
- res(new Error(e.toString()));
+ if (user?.dropboxRefresh) {
+ console.log('*********** try refresh dropbox for: ' + user.email + ' ***********');
+ this.refreshDropboxToken(user).then(token => {
+ if (!token) {
+ console.log('Dropbox error: cannot refresh token');
+ res(new Error(e.toString()));
+ } else {
+ const dbxNew = new Dropbox({ accessToken: user.dropboxToken || '' });
+ dbxNew
+ .filesUpload({ path: `/Apps/browndash/${path.basename(fileUrl)}`, contents })
+ .then(response => {
+ dbxNew
+ .filesGetTemporaryLink({ path: response.result.path_display ?? '' })
+ .then(link => res(link.result.link))
+ .catch(linkErr => res(new Error(linkErr.toString())));
+ })
+ .catch(uploadErr => {
+ console.log('Dropbox error:', uploadErr);
+ res(new Error(uploadErr.toString()));
+ });
+ }
+ });
+ } else {
+ console.log('Dropbox error:', e);
+ res(new Error(e.toString()));
+ }
});
}
})
@@ -230,12 +256,35 @@ export default class FireflyManager extends ApiManager {
);
return fetched;
};
+
+ refreshDropboxToken = (user: DashUserModel) =>
+ axios
+ .post(
+ 'https://api.dropbox.com/oauth2/token',
+ new URLSearchParams({
+ refresh_token: user.dropboxRefresh || '',
+ grant_type: 'refresh_token',
+ client_id: process.env._CLIENT_DROPBOX_CLIENT_ID || '',
+ client_secret: process.env._CLIENT_DROPBOX_SECRET || '',
+ }).toString()
+ )
+ .then(refresh => {
+ console.log('***** dropbox token refreshed for ' + user?.email + ' ******* ');
+ user.dropboxToken = refresh.data.access_token;
+ user.save();
+ return user.dropboxToken;
+ })
+ .catch(e => {
+ console.log(e);
+ return undefined;
+ });
+
protected initialize(register: Registration): void {
register({
method: Method.POST,
subscription: '/queryFireflyImageFromStructure',
secureHandler: async ({ req, res }) =>
- this.uploadImageToDropbox(req.body.structureUrl).then(uploadUrl =>
+ this.uploadImageToDropbox(req.body.structureUrl, req.user as DashUserModel).then(uploadUrl =>
uploadUrl instanceof Error
? _invalid(res, uploadUrl.message)
: this.generateImageFromStructure(req.body.prompt, req.body.width, req.body.height, uploadUrl, req.body.strength, req.body.styles).then(fire =>
@@ -275,7 +324,7 @@ export default class FireflyManager extends ApiManager {
method: Method.POST,
subscription: '/expandImage',
secureHandler: ({ req, res }) =>
- this.uploadImageToDropbox(req.body.file).then(uploadUrl =>
+ this.uploadImageToDropbox(req.body.file, req.user as DashUserModel).then(uploadUrl =>
uploadUrl instanceof Error
? _invalid(res, uploadUrl.message)
: this.expandImage(uploadUrl, req.body.prompt).then(text => {
@@ -288,5 +337,40 @@ export default class FireflyManager extends ApiManager {
})
),
});
+
+ // construct this url and send user to it. It will allow them to authorize their dropbox account and will send the resulting token to our endpoint /refreshDropbox
+ // https://www.dropbox.com/oauth2/authorize?client_id=DROPBOX_CLIENT_ID&response_type=code&token_access_type=offline&redirect_uri=http://localhost:1050/refreshDropbox
+ // see: https://dropbox.tech/developers/using-oauth-2-0-with-offline-access
+ //
+ register({
+ method: Method.GET,
+ subscription: '/refreshDropbox',
+ secureHandler: ({ req, res }) => {
+ const user = req.user as DashUserModel;
+ console.log(`******************* dropbox authorized for ${user?.email} ******************`);
+ _success(res, 'dropbox authorized for ' + user?.email);
+
+ const data = new URLSearchParams({
+ code: req.query.code as string,
+ grant_type: 'authorization_code',
+ client_id: process.env._CLIENT_DROPBOX_CLIENT_ID ?? '',
+ client_secret: process.env._CLIENT_DROPBOX_SECRET ?? '',
+ redirect_uri: 'http://localhost:1050/refreshDropbox',
+ });
+ axios
+ .post('https://api.dropbox.com/oauth2/token', data.toString())
+ .then(response => {
+ console.log('***** dropbox token (and refresh) received for ' + user?.email + ' ******* ');
+ user.dropboxToken = response.data.access_token;
+ user.dropboxRefresh = response.data.refresh_token;
+ user.save();
+
+ setTimeout(() => this.refreshDropboxToken(user), response.data.expires_in - 600);
+ })
+ .catch(e => {
+ console.log(e);
+ });
+ },
+ });
}
}
diff --git a/src/server/authentication/DashUserModel.ts b/src/server/authentication/DashUserModel.ts
index bfa6d7bdb..debeef60c 100644
--- a/src/server/authentication/DashUserModel.ts
+++ b/src/server/authentication/DashUserModel.ts
@@ -9,6 +9,9 @@ export type DashUserModel = mongoose.Document & {
passwordResetToken?: string;
passwordResetExpires?: Date;
+ dropboxRefresh?: string;
+ dropboxToken?: string;
+
userDocumentId: string;
sharingDocumentId: string;
linkDatabaseId: string;
@@ -37,6 +40,8 @@ const userSchema = new mongoose.Schema(
passwordResetToken: String,
passwordResetExpires: Date,
+ dropboxRefresh: String,
+ dropboxToken: String,
userDocumentId: String, // id that identifies a document which hosts all of a user's account data
sharingDocumentId: String, // id that identifies a document that stores documents shared to a user, their user color, and any additional info needed to communicate between users
linkDatabaseId: String,