-
Notifications
You must be signed in to change notification settings - Fork 81
/
Copy pathjira-oauth-service.js
137 lines (115 loc) · 4.86 KB
/
jira-oauth-service.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
import { executeService } from "../common/proxy";
import { ApiUrls } from "../constants/api-urls";
import { isAppBuild } from "../constants/build-info";
import { jaJiraTokenExchangeUrl } from "../constants/oauth";
import BaseService from "./base-service";
export default class JiraAuthService extends BaseService {
static dependencies = ['AjaxRequestService', 'SettingsService', 'UserService'];
constructor($request, $settings, $user) {
super();
this.$request = $request;
this.$settings = $settings;
this.$user = $user;
}
async integrateWithCred(url, uid, pwd) {
const profile = await this.$request.execute('GET',
url.clearEnd('/') + ApiUrls.mySelf.substring(1),
null, getBasicTokenHeader(uid, pwd));
if (isAppBuild) {
pwd = await executeService('SELF', 'encryptData', [pwd]);
} else {
pwd = btoa(pwd);
}
const userId = await this.$user.createUser(profile, url, { authType: 'C', uid, pwd: pwd });
//await this.$settings.set("CurrentJiraUrl", url);
await this.$settings.set("CurrentUserId", userId);
return userId;
}
async integrate(code) {
try {
return {
success: true,
userId: await this.getAndSaveToken(code)
};
} catch (err) {
console.error('Integration failed: ', err);
return { success: false, message: err.message };
}
}
// This function returns userid when it is not passed
// and returns bearer token when user id is passed
async getAndSaveToken(authCode, refreshToken, userId) {
const returnUserId = !userId;
let result;
try {
result = await this.$request.execute('GET', jaJiraTokenExchangeUrl, null,
authCode ? { withCredentials: false, 'jira-auth-code': authCode } :
{ withCredentials: false, 'jira-refresh-token': refreshToken });
} catch (ex) {
console.error('Error fectching jira cloud auth token', ex);
throw ex;
}
const {
success, message,
token, refresh_token, expires_at: expires,
jiraUrl, cloudId, apiUrl
} = result;
if (success) {
if (!userId) {
const profile = await this.$request.execute('GET',
apiUrl.clearEnd('/') + ApiUrls.mySelf.substring(1),
null, getBearerTokenHeader(token));
userId = await this.$user.createUser(profile, jiraUrl, apiUrl);
}
await this.saveTokenData(userId, token, expires, refresh_token, cloudId);
return returnUserId ? userId : { token, expires };
} else {
throw Error(message);
}
}
async saveTokenData(userId, token, expires, refresh_token, cloudId) {
await this.$settings.saveGeneralSetting(userId, 'JOAT', { token, expires });
await this.$settings.saveGeneralSetting(userId, 'JOART', refresh_token);
await this.$settings.saveGeneralSetting(userId, 'JiraCloudId', cloudId);
}
async transformHeaders(userId, customHeaders) {
if (!userId) {
return customHeaders;
}
const user = await this.$user.getUser(userId);
if (user.authType === 'C') {
let pwd;
if (isAppBuild) {
pwd = await executeService('SELF', 'decryptData', [user.pwd]);
} else {
pwd = user.pwd && atob(user.pwd);
}
customHeaders = { ...customHeaders, ...getBasicTokenHeader(user.uid, pwd) };
}
else if (user.apiUrl) {
let auth = await this.$settings.getGeneralSetting(userId, 'JOAT');
if (auth) {
// Handle simultaneous multi executions of
if (this._tokenRefreshRunning) {
await this._tokenRefreshRunning; // Wait for running promise to complete
}
if (auth.expires <= new Date().getTime()) {
const refreshToken = await this.$settings.getGeneralSetting(userId, 'JOART');
// Store reference of running promise
this._tokenRefreshRunning = this.getAndSaveToken(null, refreshToken, userId);
auth = await this._tokenRefreshRunning;
delete this._tokenRefreshRunning; // Remove reference
}
const { token } = auth;
customHeaders = { ...customHeaders, ...getBearerTokenHeader(token) };
}
}
return customHeaders;
}
}
function getBearerTokenHeader(token) {
return { 'Authorization': `Bearer ${token}`, withCredentials: false };
}
function getBasicTokenHeader(uid, pwd) {
return { 'Authorization': `Basic ${btoa(`${uid}:${pwd}`)}`, withCredentials: false };
}