-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauthentication.js
142 lines (118 loc) · 3.96 KB
/
authentication.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
'use strict';
const baseOauthUrl = process.env.BASE_URL;
// To get your OAuth2 redirect URI, run `zapier describe` and update this variable.
// Will look like 'https://zapier.com/dashboard/auth/oauth/return/App123CLIAPI/'
const redirectUri = 'https://zapier.com/dashboard/auth/oauth/return/CrowdinCLIAPI/';
const getAuthorizeURL = (z, bundle) => {
let url = `${baseOauthUrl}/oauth/authorize`;
const urlParts = [
`client_id=${process.env.CLIENT_ID}`,
`redirect_uri=${encodeURIComponent(bundle.inputData.redirect_uri)}`,
'response_type=code',
];
urlParts.push(`state=${bundle.inputData.state}`);
return `${url}?${urlParts.join('&')}`;
}
const getAccessToken = (z, bundle) => {
let url = `${baseOauthUrl}/oauth/token`;
const body = {
code: bundle.inputData.code,
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
grant_type: 'authorization_code',
redirect_uri: redirectUri
};
const promise = z.request(url, {
method: 'POST',
body,
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
});
return promise.then((response) => {
if (response.status !== 200) {
throw new Error('Unable to fetch access token: ' + response.content);
}
const result = z.JSON.parse(response.content);
const domainName = parseJwt(result.access_token).domain;
return {
access_token: result.access_token,
refresh_token: result.refresh_token,
domain: domainName,
connectionLabel: (domainName ? `Crowdin Enterprise (org. ${domainName})` : 'crowdin.com')
};
});
};
const refreshAccessToken = (z, bundle) => {
let url = `${baseOauthUrl}/oauth/token`;
const body = {
refresh_token: bundle.authData.refresh_token,
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
grant_type: 'refresh_token',
};
const promise = z.request(url, {
method: 'POST',
body,
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
});
return promise.then((response) => {
if (response.status !== 200) {
throw new Error('Unable to fetch access token: ' + response.content);
}
const result = z.JSON.parse(response.content);
const domainName = parseJwt(result.access_token).domain;
return {
access_token: result.access_token,
refresh_token: result.refresh_token,
domain: domainName,
connectionLabel: domainName ? `Crowdin Enterprise (org. ${domainName})` : 'crowdin.com'
};
});
};
function parseJwt(token) {
const payload = Buffer.from(token.split(".")[1], "base64");
return JSON.parse(payload);
}
// The test call Zapier makes to ensure an access token is valid
// UX TIP: Hit an endpoint that always returns data with valid credentials,
// like a /profile or /me endpoint. That way the success/failure is related to
// the token and not because the user didn't happen to have a recently created record.
const testAuth = (z, bundle) => {
let domain = ''
if (bundle.authData.domain) {
domain = `${bundle.authData.domain}.`;
}
const options = {
url: `https://${domain}api.crowdin.com/api/v2/user`,
method: 'GET',
headers: {
Authorization: `Bearer ${bundle.authData.access_token}`,
}
};
return z.request(options).then((response) => {
response.throwForStatus();
const results = response.json;
if (results.code == 401) { //we never received 401 in this callback :(
throw new z.errors.RefreshAuthError();
}
return results;
}).catch((e, b) => {
z.console.log("Unable to check user. TODO: check response status ", e, b)
throw new z.errors.RefreshAuthError(); //TODO: this is not right, we have to check the response header
});
};
module.exports = {
type: 'oauth2',
connectionLabel: '{{bundle.authData.connectionLabel}}',
oauth2Config: {
authorizeUrl: getAuthorizeURL,
getAccessToken,
refreshAccessToken,
autoRefresh: true,
scope: 'project group mt vendor',
},
test: testAuth
};