1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | var __assign = (this && this.__assign) || function () {
|
14 | __assign = Object.assign || function(t) {
|
15 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
16 | s = arguments[i];
|
17 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
18 | t[p] = s[p];
|
19 | }
|
20 | return t;
|
21 | };
|
22 | return __assign.apply(this, arguments);
|
23 | };
|
24 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
25 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
26 | return new (P || (P = Promise))(function (resolve, reject) {
|
27 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
28 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
29 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
30 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
31 | });
|
32 | };
|
33 | var __generator = (this && this.__generator) || function (thisArg, body) {
|
34 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
35 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
36 | function verb(n) { return function (v) { return step([n, v]); }; }
|
37 | function step(op) {
|
38 | if (f) throw new TypeError("Generator is already executing.");
|
39 | while (_) try {
|
40 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
41 | if (y = 0, t) op = [op[0] & 2, t.value];
|
42 | switch (op[0]) {
|
43 | case 0: case 1: t = op; break;
|
44 | case 4: _.label++; return { value: op[1], done: false };
|
45 | case 5: _.label++; y = op[1]; op = [0]; continue;
|
46 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
47 | default:
|
48 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
49 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
50 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
51 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
52 | if (t[2]) _.ops.pop();
|
53 | _.trys.pop(); continue;
|
54 | }
|
55 | op = body.call(thisArg, _);
|
56 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
57 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
58 | }
|
59 | };
|
60 | var __read = (this && this.__read) || function (o, n) {
|
61 | var m = typeof Symbol === "function" && o[Symbol.iterator];
|
62 | if (!m) return o;
|
63 | var i = m.call(o), r, ar = [], e;
|
64 | try {
|
65 | while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
66 | }
|
67 | catch (error) { e = { error: error }; }
|
68 | finally {
|
69 | try {
|
70 | if (r && !r.done && (m = i["return"])) m.call(i);
|
71 | }
|
72 | finally { if (e) throw e.error; }
|
73 | }
|
74 | return ar;
|
75 | };
|
76 | import { parse } from 'url';
|
77 | import { launchUri } from './urlOpener';
|
78 | import * as oAuthStorage from './oauthStorage';
|
79 | import { isCognitoHostedOpts, CognitoHostedUIIdentityProvider, } from '../types/Auth';
|
80 | import { ConsoleLogger as Logger, Hub, urlSafeEncode } from '@aws-amplify/core';
|
81 | import sha256 from 'crypto-js/sha256';
|
82 | import Base64 from 'crypto-js/enc-base64';
|
83 | var AMPLIFY_SYMBOL = (typeof Symbol !== 'undefined' &&
|
84 | typeof Symbol.for === 'function'
|
85 | ? Symbol.for('amplify_default')
|
86 | : '@@amplify_default');
|
87 | var dispatchAuthEvent = function (event, data, message) {
|
88 | Hub.dispatch('auth', { event: event, data: data, message: message }, 'Auth', AMPLIFY_SYMBOL);
|
89 | };
|
90 | var logger = new Logger('OAuth');
|
91 | var OAuth = (function () {
|
92 | function OAuth(_a) {
|
93 | var config = _a.config, cognitoClientId = _a.cognitoClientId, _b = _a.scopes, scopes = _b === void 0 ? [] : _b;
|
94 | this._urlOpener = config.urlOpener || launchUri;
|
95 | this._config = config;
|
96 | this._cognitoClientId = cognitoClientId;
|
97 | if (!this.isValidScopes(scopes))
|
98 | throw Error('scopes must be a String Array');
|
99 | this._scopes = scopes;
|
100 | }
|
101 | OAuth.prototype.isValidScopes = function (scopes) {
|
102 | return (Array.isArray(scopes) && scopes.every(function (scope) { return typeof scope === 'string'; }));
|
103 | };
|
104 | OAuth.prototype.oauthSignIn = function (responseType, domain, redirectSignIn, clientId, provider, customState) {
|
105 | if (responseType === void 0) { responseType = 'code'; }
|
106 | if (provider === void 0) { provider = CognitoHostedUIIdentityProvider.Cognito; }
|
107 | var generatedState = this._generateState(32);
|
108 | |
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 | var state = customState
|
115 | ? generatedState + "-" + urlSafeEncode(customState)
|
116 | : generatedState;
|
117 | oAuthStorage.setState(state);
|
118 | var pkce_key = this._generateRandom(128);
|
119 | oAuthStorage.setPKCE(pkce_key);
|
120 | var code_challenge = this._generateChallenge(pkce_key);
|
121 | var code_challenge_method = 'S256';
|
122 | var scopesString = this._scopes.join(' ');
|
123 | var queryString = Object.entries(__assign(__assign({ redirect_uri: redirectSignIn, response_type: responseType, client_id: clientId, identity_provider: provider, scope: scopesString, state: state }, (responseType === 'code' ? { code_challenge: code_challenge } : {})), (responseType === 'code' ? { code_challenge_method: code_challenge_method } : {})))
|
124 | .map(function (_a) {
|
125 | var _b = __read(_a, 2), k = _b[0], v = _b[1];
|
126 | return encodeURIComponent(k) + "=" + encodeURIComponent(v);
|
127 | })
|
128 | .join('&');
|
129 | var URL = "https://" + domain + "/oauth2/authorize?" + queryString;
|
130 | logger.debug("Redirecting to " + URL);
|
131 | this._urlOpener(URL, redirectSignIn);
|
132 | };
|
133 | OAuth.prototype._handleCodeFlow = function (currentUrl) {
|
134 | return __awaiter(this, void 0, void 0, function () {
|
135 | var code, currentUrlPathname, redirectSignInPathname, oAuthTokenEndpoint, client_id, redirect_uri, code_verifier, oAuthTokenBody, body, _a, access_token, refresh_token, id_token, error;
|
136 | return __generator(this, function (_b) {
|
137 | switch (_b.label) {
|
138 | case 0:
|
139 | code = (parse(currentUrl).query || '')
|
140 | .split('&')
|
141 | .map(function (pairings) { return pairings.split('='); })
|
142 | .reduce(function (accum, _a) {
|
143 | var _b;
|
144 | var _c = __read(_a, 2), k = _c[0], v = _c[1];
|
145 | return (__assign(__assign({}, accum), (_b = {}, _b[k] = v, _b)));
|
146 | }, { code: undefined }).code;
|
147 | currentUrlPathname = parse(currentUrl).pathname || '/';
|
148 | redirectSignInPathname = parse(this._config.redirectSignIn).pathname || '/';
|
149 | if (!code || currentUrlPathname !== redirectSignInPathname) {
|
150 | return [2 ];
|
151 | }
|
152 | oAuthTokenEndpoint = 'https://' + this._config.domain + '/oauth2/token';
|
153 | dispatchAuthEvent('codeFlow', {}, "Retrieving tokens from " + oAuthTokenEndpoint);
|
154 | client_id = isCognitoHostedOpts(this._config)
|
155 | ? this._cognitoClientId
|
156 | : this._config.clientID;
|
157 | redirect_uri = isCognitoHostedOpts(this._config)
|
158 | ? this._config.redirectSignIn
|
159 | : this._config.redirectUri;
|
160 | code_verifier = oAuthStorage.getPKCE();
|
161 | oAuthTokenBody = __assign({ grant_type: 'authorization_code', code: code,
|
162 | client_id: client_id,
|
163 | redirect_uri: redirect_uri }, (code_verifier ? { code_verifier: code_verifier } : {}));
|
164 | logger.debug("Calling token endpoint: " + oAuthTokenEndpoint + " with", oAuthTokenBody);
|
165 | body = Object.entries(oAuthTokenBody)
|
166 | .map(function (_a) {
|
167 | var _b = __read(_a, 2), k = _b[0], v = _b[1];
|
168 | return encodeURIComponent(k) + "=" + encodeURIComponent(v);
|
169 | })
|
170 | .join('&');
|
171 | return [4 , fetch(oAuthTokenEndpoint, {
|
172 | method: 'POST',
|
173 | headers: {
|
174 | 'Content-Type': 'application/x-www-form-urlencoded',
|
175 | },
|
176 | body: body,
|
177 | })];
|
178 | case 1: return [4 , (_b.sent()).json()];
|
179 | case 2:
|
180 | _a = _b.sent(), access_token = _a.access_token, refresh_token = _a.refresh_token, id_token = _a.id_token, error = _a.error;
|
181 | if (error) {
|
182 | throw new Error(error);
|
183 | }
|
184 | return [2 , {
|
185 | accessToken: access_token,
|
186 | refreshToken: refresh_token,
|
187 | idToken: id_token,
|
188 | }];
|
189 | }
|
190 | });
|
191 | });
|
192 | };
|
193 | OAuth.prototype._handleImplicitFlow = function (currentUrl) {
|
194 | return __awaiter(this, void 0, void 0, function () {
|
195 | var _a, id_token, access_token;
|
196 | return __generator(this, function (_b) {
|
197 | _a = (parse(currentUrl).hash || '#')
|
198 | .substr(1)
|
199 | .split('&')
|
200 | .map(function (pairings) { return pairings.split('='); })
|
201 | .reduce(function (accum, _a) {
|
202 | var _b;
|
203 | var _c = __read(_a, 2), k = _c[0], v = _c[1];
|
204 | return (__assign(__assign({}, accum), (_b = {}, _b[k] = v, _b)));
|
205 | }, {
|
206 | id_token: undefined,
|
207 | access_token: undefined,
|
208 | }), id_token = _a.id_token, access_token = _a.access_token;
|
209 | dispatchAuthEvent('implicitFlow', {}, "Got tokens from " + currentUrl);
|
210 | logger.debug("Retrieving implicit tokens from " + currentUrl + " with");
|
211 | return [2 , {
|
212 | accessToken: access_token,
|
213 | idToken: id_token,
|
214 | refreshToken: null,
|
215 | }];
|
216 | });
|
217 | });
|
218 | };
|
219 | OAuth.prototype.handleAuthResponse = function (currentUrl) {
|
220 | return __awaiter(this, void 0, void 0, function () {
|
221 | var urlParams, error, error_description, state, _a, _b, e_1;
|
222 | return __generator(this, function (_c) {
|
223 | switch (_c.label) {
|
224 | case 0:
|
225 | _c.trys.push([0, 5, , 6]);
|
226 | urlParams = currentUrl
|
227 | ? __assign(__assign({}, (parse(currentUrl).hash || '#')
|
228 | .substr(1)
|
229 | .split('&')
|
230 | .map(function (entry) { return entry.split('='); })
|
231 | .reduce(function (acc, _a) {
|
232 | var _b = __read(_a, 2), k = _b[0], v = _b[1];
|
233 | return ((acc[k] = v), acc);
|
234 | }, {})), (parse(currentUrl).query || '')
|
235 | .split('&')
|
236 | .map(function (entry) { return entry.split('='); })
|
237 | .reduce(function (acc, _a) {
|
238 | var _b = __read(_a, 2), k = _b[0], v = _b[1];
|
239 | return ((acc[k] = v), acc);
|
240 | }, {}))
|
241 | : {};
|
242 | error = urlParams.error, error_description = urlParams.error_description;
|
243 | if (error) {
|
244 | throw new Error(error_description);
|
245 | }
|
246 | state = this._validateState(urlParams);
|
247 | logger.debug("Starting " + this._config.responseType + " flow with " + currentUrl);
|
248 | if (!(this._config.responseType === 'code')) return [3 , 2];
|
249 | _a = [{}];
|
250 | return [4 , this._handleCodeFlow(currentUrl)];
|
251 | case 1: return [2 , __assign.apply(void 0, [__assign.apply(void 0, _a.concat([(_c.sent())])), { state: state }])];
|
252 | case 2:
|
253 | _b = [{}];
|
254 | return [4 , this._handleImplicitFlow(currentUrl)];
|
255 | case 3: return [2 , __assign.apply(void 0, [__assign.apply(void 0, _b.concat([(_c.sent())])), { state: state }])];
|
256 | case 4: return [3 , 6];
|
257 | case 5:
|
258 | e_1 = _c.sent();
|
259 | logger.error("Error handling auth response.", e_1);
|
260 | throw e_1;
|
261 | case 6: return [2 ];
|
262 | }
|
263 | });
|
264 | });
|
265 | };
|
266 | OAuth.prototype._validateState = function (urlParams) {
|
267 | if (!urlParams) {
|
268 | return;
|
269 | }
|
270 | var savedState = oAuthStorage.getState();
|
271 | var returnedState = urlParams.state;
|
272 |
|
273 | if (savedState && savedState !== returnedState) {
|
274 | throw new Error('Invalid state in OAuth flow');
|
275 | }
|
276 | return returnedState;
|
277 | };
|
278 | OAuth.prototype.signOut = function () {
|
279 | return __awaiter(this, void 0, void 0, function () {
|
280 | var oAuthLogoutEndpoint, client_id, signout_uri;
|
281 | return __generator(this, function (_a) {
|
282 | oAuthLogoutEndpoint = 'https://' + this._config.domain + '/logout?';
|
283 | client_id = isCognitoHostedOpts(this._config)
|
284 | ? this._cognitoClientId
|
285 | : this._config.oauth.clientID;
|
286 | signout_uri = isCognitoHostedOpts(this._config)
|
287 | ? this._config.redirectSignOut
|
288 | : this._config.returnTo;
|
289 | oAuthLogoutEndpoint += Object.entries({
|
290 | client_id: client_id,
|
291 | logout_uri: encodeURIComponent(signout_uri),
|
292 | })
|
293 | .map(function (_a) {
|
294 | var _b = __read(_a, 2), k = _b[0], v = _b[1];
|
295 | return k + "=" + v;
|
296 | })
|
297 | .join('&');
|
298 | dispatchAuthEvent('oAuthSignOut', { oAuth: 'signOut' }, "Signing out from " + oAuthLogoutEndpoint);
|
299 | logger.debug("Signing out from " + oAuthLogoutEndpoint);
|
300 | return [2 , this._urlOpener(oAuthLogoutEndpoint, signout_uri)];
|
301 | });
|
302 | });
|
303 | };
|
304 | OAuth.prototype._generateState = function (length) {
|
305 | var result = '';
|
306 | var i = length;
|
307 | var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
308 | for (; i > 0; --i)
|
309 | result += chars[Math.round(Math.random() * (chars.length - 1))];
|
310 | return result;
|
311 | };
|
312 | OAuth.prototype._generateChallenge = function (code) {
|
313 | return this._base64URL(sha256(code));
|
314 | };
|
315 | OAuth.prototype._base64URL = function (string) {
|
316 | return string
|
317 | .toString(Base64)
|
318 | .replace(/=/g, '')
|
319 | .replace(/\+/g, '-')
|
320 | .replace(/\//g, '_');
|
321 | };
|
322 | OAuth.prototype._generateRandom = function (size) {
|
323 | var CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
|
324 | var buffer = new Uint8Array(size);
|
325 | if (typeof window !== 'undefined' && !!window.crypto) {
|
326 | window.crypto.getRandomValues(buffer);
|
327 | }
|
328 | else {
|
329 | for (var i = 0; i < size; i += 1) {
|
330 | buffer[i] = (Math.random() * CHARSET.length) | 0;
|
331 | }
|
332 | }
|
333 | return this._bufferToString(buffer);
|
334 | };
|
335 | OAuth.prototype._bufferToString = function (buffer) {
|
336 | var CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
337 | var state = [];
|
338 | for (var i = 0; i < buffer.byteLength; i += 1) {
|
339 | var index = buffer[i] % CHARSET.length;
|
340 | state.push(CHARSET[index]);
|
341 | }
|
342 | return state.join('');
|
343 | };
|
344 | return OAuth;
|
345 | }());
|
346 | export default OAuth;
|
347 |
|
\ | No newline at end of file |