aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/apis/google/GoogleApiServerUtils.ts51
-rw-r--r--src/server/database.ts34
-rw-r--r--src/server/index.ts12
3 files changed, 52 insertions, 45 deletions
diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts
index 684a8081b..665dcf862 100644
--- a/src/server/apis/google/GoogleApiServerUtils.ts
+++ b/src/server/apis/google/GoogleApiServerUtils.ts
@@ -66,6 +66,15 @@ export namespace GoogleApiServerUtils {
});
};
+ export const RetrieveAccessToken = (information: CredentialInformation) => {
+ return new Promise<string>((resolve, reject) => {
+ RetrieveCredentials(information).then(
+ credentials => resolve(credentials.token.access_token!),
+ error => reject(`Error: unable to authenticate Google Photos API request.\n${error}`)
+ );
+ });
+ };
+
export const RetrieveCredentials = (information: CredentialInformation) => {
return new Promise<TokenResult>((resolve, reject) => {
readFile(information.credentialsPath, async (err, credentials) => {
@@ -78,15 +87,6 @@ export namespace GoogleApiServerUtils {
});
};
- export const RetrieveAccessToken = (information: CredentialInformation) => {
- return new Promise<string>((resolve, reject) => {
- RetrieveCredentials(information).then(
- credentials => resolve(credentials.token.access_token!),
- error => reject(`Error: unable to authenticate Google Photos API request.\n${error}`)
- );
- });
- };
-
export const RetrievePhotosEndpoint = (paths: CredentialInformation) => {
return new Promise<any>((resolve, reject) => {
RetrieveAccessToken(paths).then(
@@ -107,7 +107,7 @@ export namespace GoogleApiServerUtils {
client_id, client_secret, redirect_uris[0]);
return new Promise<TokenResult>((resolve, reject) => {
- Database.Auxiliary.FetchGoogleAuthenticationToken(userId).then(token => {
+ Database.Auxiliary.GoogleAuthenticationToken.Fetch(userId).then(token => {
// Check if we have previously stored a token for this userId.
if (!token) {
return getNewToken(oAuth2Client, userId).then(resolve, reject);
@@ -123,8 +123,8 @@ export namespace GoogleApiServerUtils {
}
const refreshEndpoint = "https://oauth2.googleapis.com/token";
- const refreshToken = (credentials: Credentials, client_id: string, client_secret: string, oAuth2Client: OAuth2Client, token_path: string) => {
- return new Promise<TokenResult>((resolve, reject) => {
+ const refreshToken = (credentials: Credentials, client_id: string, client_secret: string, oAuth2Client: OAuth2Client, userId: string) => {
+ return new Promise<TokenResult>(resolve => {
let headerParameters = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } };
let queryParameters = {
refreshToken: credentials.refresh_token,
@@ -133,19 +133,13 @@ export namespace GoogleApiServerUtils {
grant_type: "refresh_token"
};
let url = `${refreshEndpoint}?${qs.stringify(queryParameters)}`;
- request.post(url, headerParameters).then(response => {
+ request.post(url, headerParameters).then(async response => {
let parsed = JSON.parse(response);
credentials.access_token = parsed.access_token;
credentials.expiry_date = new Date().getTime() + (parsed.expires_in * 1000);
- writeFile(token_path, JSON.stringify(credentials), (err) => {
- if (err) {
- console.error(err);
- reject(err);
- }
- console.log('Refreshed token stored to', token_path);
- oAuth2Client.setCredentials(credentials);
- resolve({ token: credentials, client: oAuth2Client });
- });
+ oAuth2Client.setCredentials(credentials);
+ await Database.Auxiliary.GoogleAuthenticationToken.Write(userId, credentials);
+ resolve({ token: credentials, client: oAuth2Client });
});
});
};
@@ -156,7 +150,7 @@ export namespace GoogleApiServerUtils {
* @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
* @param {getEventsCallback} callback The callback for the authorized client.
*/
- function getNewToken(oAuth2Client: OAuth2Client, token_path: string) {
+ function getNewToken(oAuth2Client: OAuth2Client, userId: string) {
return new Promise<TokenResult>((resolve, reject) => {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
@@ -169,20 +163,13 @@ export namespace GoogleApiServerUtils {
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
- oAuth2Client.getToken(code, (err, token) => {
+ oAuth2Client.getToken(code, async (err, token) => {
if (err || !token) {
reject(err);
return console.error('Error retrieving access token', err);
}
oAuth2Client.setCredentials(token);
- // Store the token to disk for later program executions
- writeFile(token_path, JSON.stringify(token), (err) => {
- if (err) {
- console.error(err);
- reject(err);
- }
- console.log('Token stored to', token_path);
- });
+ await Database.Auxiliary.GoogleAuthenticationToken.Write(userId, token);
resolve({ token, client: oAuth2Client });
});
});
diff --git a/src/server/database.ts b/src/server/database.ts
index ce29478ad..890ac6b32 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -231,19 +231,37 @@ export namespace Database {
const GoogleAuthentication = "GoogleAuthentication";
- const SanitizedSingletonQuery = async (query: { [key: string]: any }, collection: string) => {
+ const SanitizedCappedQuery = async (query: { [key: string]: any }, collection: string, cap: number) => {
const cursor = await Instance.query(query, undefined, collection);
- const existing = (await cursor.toArray())[0];
- if (existing) {
- delete existing._id;
- }
- return existing;
+ const results = await cursor.toArray();
+ const slice = results.slice(0, Math.min(cap, results.length));
+ return slice.map(result => {
+ delete result._id;
+ return result;
+ });
+ };
+
+ const SanitizedSingletonQuery = async (query: { [key: string]: any }, collection: string) => {
+ const results = await SanitizedCappedQuery(query, collection, 1);
+ return results.length ? results[0] : undefined;
};
export const QueryUploadHistory = async (contentSize: number): Promise<Opt<DashUploadUtils.UploadInformation>> => {
return SanitizedSingletonQuery({ contentSize }, AuxiliaryCollections.GooglePhotosUploadHistory);
};
+ export namespace GoogleAuthenticationToken {
+
+ export const Fetch = async (userId: string) => {
+ return SanitizedSingletonQuery({ userId }, GoogleAuthentication);
+ };
+
+ export const Write = async (userId: string, token: any) => {
+ return Instance.insert({ userId, ...token }, GoogleAuthentication);
+ };
+
+ }
+
export const LogUpload = async (information: DashUploadUtils.UploadInformation) => {
const bundle = {
_id: Utils.GenerateDeterministicGuid(String(information.contentSize!)),
@@ -258,10 +276,6 @@ export namespace Database {
return Promise.all(pendingDeletions);
};
- export const FetchGoogleAuthenticationToken = async (userId: string) => {
- return SanitizedSingletonQuery({ userId }, GoogleAuthentication);
- };
-
}
} \ No newline at end of file
diff --git a/src/server/index.ts b/src/server/index.ts
index 386ecce4d..2ff63ab78 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -810,7 +810,7 @@ const EndpointHandlerMap = new Map<GoogleApiServerUtils.Action, GoogleApiServerU
app.post(RouteStore.googleDocs + "/:sector/:action", (req, res) => {
let sector: GoogleApiServerUtils.Service = req.params.sector as GoogleApiServerUtils.Service;
let action: GoogleApiServerUtils.Action = req.params.action as GoogleApiServerUtils.Action;
- GoogleApiServerUtils.GetEndpoint(GoogleApiServerUtils.Service[sector], { credentialsPath, userId: req.body.userId }).then(endpoint => {
+ GoogleApiServerUtils.GetEndpoint(GoogleApiServerUtils.Service[sector], { credentialsPath, userId: req.headers.userId as string }).then(endpoint => {
let handler = EndpointHandlerMap.get(action);
if (endpoint && handler) {
let execute = handler(endpoint, req.body).then(
@@ -824,10 +824,11 @@ app.post(RouteStore.googleDocs + "/:sector/:action", (req, res) => {
});
});
-app.get(RouteStore.googlePhotosAccessToken, (req, res) => GoogleApiServerUtils.RetrieveAccessToken({ credentialsPath, userId: req.body.userId }).then(token => res.send(token)));
+app.get(RouteStore.googlePhotosAccessToken, (req, res) => GoogleApiServerUtils.RetrieveAccessToken({ credentialsPath, userId: req.headers.userId as string }).then(token => res.send(token)));
const tokenError = "Unable to successfully upload bytes for all images!";
const mediaError = "Unable to convert all uploaded bytes to media items!";
+const userIdError = "Unable to parse the identification of the user!";
export interface NewMediaItem {
description: string;
@@ -837,7 +838,12 @@ export interface NewMediaItem {
}
app.post(RouteStore.googlePhotosMediaUpload, async (req, res) => {
- const { userId, media } = req.body;
+ const { media } = req.body;
+ const { userId } = req.headers;
+
+ if (!userId || Array.isArray(userId)) {
+ return _error(res, userIdError);
+ }
await GooglePhotosUploadUtils.initialize({ credentialsPath, userId });