forked from authorizerdev/authorizer-js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.ts
More file actions
157 lines (130 loc) · 4.33 KB
/
Copy pathutils.ts
File metadata and controls
157 lines (130 loc) · 4.33 KB
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import {
CLEANUP_IFRAME_TIMEOUT_IN_SECONDS,
DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS,
} from './constants';
import { AuthorizeResponse } from './types';
export const hasWindow = (): boolean => typeof window !== 'undefined';
export const trimURL = (url: string): string => {
let trimmedData = url.trim();
const lastChar = trimmedData[trimmedData.length - 1];
if (lastChar === '/') {
trimmedData = trimmedData.slice(0, -1);
} else {
trimmedData = trimmedData;
}
return trimmedData;
};
export const getCrypto = () => {
//ie 11.x uses msCrypto
return hasWindow()
? ((window.crypto || (window as any).msCrypto) as Crypto)
: null;
};
export const getCryptoSubtle = () => {
const crypto = getCrypto();
//safari 10.x uses webkitSubtle
return (crypto && crypto.subtle) || (crypto as any).webkitSubtle;
};
export const createRandomString = () => {
const charset =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.';
let random = '';
const crypto = getCrypto();
if (crypto) {
const randomValues = Array.from(crypto.getRandomValues(new Uint8Array(43)));
randomValues.forEach((v) => (random += charset[v % charset.length]));
}
return random;
};
export const encode = (value: string) =>
hasWindow() ? btoa(value) : Buffer.from(value).toString('base64');
export const decode = (value: string) =>
hasWindow() ? atob(value) : Buffer.from(value, 'base64').toString('ascii');
export const createQueryParams = (params: any) => {
return Object.keys(params)
.filter((k) => typeof params[k] !== 'undefined')
.map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
.join('&');
};
export const sha256 = async (s: string) => {
const digestOp: any = getCryptoSubtle().digest(
{ name: 'SHA-256' },
new TextEncoder().encode(s),
);
// msCrypto (IE11) uses the old spec, which is not Promise based
// https://msdn.microsoft.com/en-us/expression/dn904640(v=vs.71)
if ((window as any).msCrypto) {
return new Promise((res, rej) => {
digestOp.oncomplete = (e: any) => {
res(e.target.result);
};
digestOp.onerror = (e: ErrorEvent) => {
rej(e.error);
};
digestOp.onabort = () => {
rej('The digest operation was aborted');
};
});
}
return await digestOp;
};
const urlEncodeB64 = (input: string) => {
const b64Chars: { [index: string]: string } = { '+': '-', '/': '_', '=': '' };
return input.replace(/[+/=]/g, (m: string) => b64Chars[m]);
};
// https://stackoverflow.com/questions/30106476/
const decodeB64 = (input: string) =>
decodeURIComponent(
atob(input)
.split('')
.map((c) => {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
})
.join(''),
);
export const urlDecodeB64 = (input: string) =>
decodeB64(input.replace(/_/g, '/').replace(/-/g, '+'));
export const bufferToBase64UrlEncoded = (input: number[] | Uint8Array) => {
const ie11SafeInput = new Uint8Array(input);
return urlEncodeB64(
window.btoa(String.fromCharCode(...Array.from(ie11SafeInput))),
);
};
export const executeIframe = (
authorizeUrl: string,
eventOrigin: string,
timeoutInSeconds: number = DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS,
) => {
return new Promise<AuthorizeResponse>((res, rej) => {
const iframe = window.document.createElement('iframe');
iframe.setAttribute('id', 'authorizer-iframe');
iframe.setAttribute('width', '0');
iframe.setAttribute('height', '0');
iframe.style.display = 'none';
const removeIframe = () => {
if (window.document.body.contains(iframe)) {
window.document.body.removeChild(iframe);
window.removeEventListener('message', iframeEventHandler, false);
}
};
let iframeEventHandler: (e: MessageEvent) => void;
const timeoutSetTimeoutId = setTimeout(() => {
removeIframe();
}, timeoutInSeconds * 1000);
iframeEventHandler = function (e: MessageEvent) {
if (e.origin != eventOrigin) return;
if (!e.data || !e.data.response) return;
const eventSource = e.source;
if (eventSource) {
(eventSource as any).close();
}
e.data.response.error ? rej(e.data.response) : res(e.data.response);
clearTimeout(timeoutSetTimeoutId);
window.removeEventListener('message', iframeEventHandler, false);
setTimeout(removeIframe, CLEANUP_IFRAME_TIMEOUT_IN_SECONDS * 1000);
};
window.addEventListener('message', iframeEventHandler, false);
window.document.body.appendChild(iframe);
iframe.setAttribute('src', authorizeUrl);
});
};