Skip to content

Commit

Permalink
Collocate OAuth code in one class
Browse files Browse the repository at this point in the history
  • Loading branch information
LFDM committed Dec 26, 2020
1 parent a8552c7 commit c76fe26
Showing 1 changed file with 45 additions and 34 deletions.
79 changes: 45 additions & 34 deletions lib/GoogleSpreadsheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,48 @@ const serializeParams = (params) => {
return options ? options.slice(0, -1) : options;
};

const refreshToken = async ({ clientId, clientSecret, refreshToken }) => {
const url = "https://oauth2.googleapis.com/token";
const data = {
refresh_token: refreshToken,
client_id: clientId,
client_secret: clientSecret,
grant_type: "refresh_token",
};
const res = await Axios.post(url, serializeParams(data), {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
return res.data;
};
class OAuthClient {
constructor(creds, onRefreshTokens, refreshThreshold = ONE_MINUTE * 2) {
this.creds = creds;
this.onRefreshTokens = onRefreshTokens;

this.refreshThreshold = refreshThreshold;
}

async refreshToken() {
const url = "https://oauth2.googleapis.com/token";
const data = {
refresh_token: this.creds.refreshToken,
client_id: this.creds.clientId,
client_secret: this.creds.clientSecret,
grant_type: "refresh_token",
};
const res = await Axios.post(url, serializeParams(data), {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
return {
accessToken: res.data.access_token,
refreshToken: res.data.refresh_token,
expiresAt: Date.now() + res.data.expires_in * 1000,
};
}

getFreshAccessToken() {
const isExpired = !this.creds.expiresAt || this.creds.expiresAt < Date.now() - this.refreshThreshold;

if (isExpired) {
// refresh the token
const nextTokens = await refreshToken({
clientId: this.oAuthCredentials.clientId,
clientSecret: this.oAuthCredentials.clientSecret,
refreshToken: this.oAuthCredentials.refreshToken
})
this.creds = { ...this.creds, ...nextTokens };
await this.oAuthRefreshCallback(nextTokens);
}
return this.creds.accessToken;
}
}


class GoogleSpreadsheet {
Expand Down Expand Up @@ -124,8 +153,7 @@ class GoogleSpreadsheet {

async useOAuthToken(creds, onRefreshTokens) {
this.authMode = AUTH_MODES.OAUTH;
this.oAuthCredentials = creds;
this.oAuthRefreshCallback = onRefreshTokens;
this.oAuthClient = new OAuthClient(creds, onRefreshTokens);
}

// creds should be an object obtained by loading the json file google gives you
Expand Down Expand Up @@ -174,25 +202,8 @@ class GoogleSpreadsheet {
config.params = config.params || {};
config.params.key = this.apiKey;
} else if (this.authMode === AUTH_MODES.OAUTH) {
const isExpired = !this.oAuthCredentials.expiresAt || this.oAuthCredentials.expiresAt < Date.now() - ONE_MINUTE * 2
if (isExpired) {
// refresh the token
const nextTokens = await refreshToken({
clientId: this.oAuthCredentials.clientId,
clientSecret: this.oAuthCredentials.clientSecret,
refreshToken: this.oAuthCredentials.refreshToken
})
this.oAuthCredentials.accessToken = nextTokens.access_token;
this.oAuthCredentials.refreshToken = nextTokens.refresh_token;
this.oAuthCredentials.expiresAt = Date.now() + nextTokens.expires_in * 1000;
await this.oAuthRefreshCallback({
accessToken: this.oAuthCredentials.accessToken,
refreshToken: this.oAuthCredentials.refreshToken,
expiresAt: this.oAuthCredentials.expiresAt
})
}

config.headers.Authorization = `Bearer ${this.oAuthCredentials.accessToken}`;
const token = await this.oAuthClient.getFreshAccessToken();
config.headers.Authorization = `Bearer ${token}`;
} else {
throw new Error('You must initialize some kind of auth before making any requests');
}
Expand Down

0 comments on commit c76fe26

Please sign in to comment.