@authorizerdev/authorizer-js 0.1.0-beta.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -1
- package/lib/authorizer.min.js +15 -1
- package/lib/authorizer.min.js.map +1 -1
- package/lib/cjs/index.d.ts +72 -42
- package/lib/cjs/index.js +239 -186
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/index.d.ts +72 -42
- package/lib/esm/index.js +235 -184
- package/lib/esm/index.js.map +1 -1
- package/package.json +7 -3
- package/src/index.ts +138 -71
package/src/index.ts
CHANGED
|
@@ -1,93 +1,132 @@
|
|
|
1
1
|
// Note: write gql query in single line to reduce bundle size
|
|
2
2
|
import nodeFetch from 'node-fetch';
|
|
3
3
|
|
|
4
|
-
type ConfigType = {
|
|
4
|
+
export type ConfigType = {
|
|
5
5
|
authorizerURL: string;
|
|
6
|
-
redirectURL
|
|
6
|
+
redirectURL: string;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
type User = {
|
|
9
|
+
export type User = {
|
|
10
10
|
id: string;
|
|
11
11
|
email: string;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
preferred_username: string;
|
|
13
|
+
email_verified: boolean;
|
|
14
|
+
signup_methods: string;
|
|
15
|
+
given_name?: string | null;
|
|
16
|
+
family_name?: string | null;
|
|
17
|
+
middle_name?: string | null;
|
|
18
|
+
picture?: string | null;
|
|
19
|
+
gender?: string | null;
|
|
20
|
+
birthdate?: string | null;
|
|
21
|
+
phone_number?: string | null;
|
|
22
|
+
phone_number_verified?: boolean | null;
|
|
23
|
+
roles?: string[];
|
|
24
|
+
created_at: number;
|
|
25
|
+
updated_at: number;
|
|
17
26
|
};
|
|
18
27
|
|
|
19
|
-
type AuthToken = {
|
|
28
|
+
export type AuthToken = {
|
|
20
29
|
message?: string;
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
access_token: string;
|
|
31
|
+
expires_at: number;
|
|
23
32
|
user?: User;
|
|
24
33
|
};
|
|
25
34
|
|
|
26
|
-
type Response = {
|
|
35
|
+
export type Response = {
|
|
27
36
|
message: string;
|
|
28
37
|
};
|
|
29
38
|
|
|
30
|
-
type Headers = Record<string, string>;
|
|
39
|
+
export type Headers = Record<string, string>;
|
|
31
40
|
|
|
32
|
-
type LoginInput = { email: string; password: string };
|
|
41
|
+
export type LoginInput = { email: string; password: string; roles?: string[] };
|
|
33
42
|
|
|
34
|
-
type SignupInput = {
|
|
43
|
+
export type SignupInput = {
|
|
35
44
|
email: string;
|
|
36
45
|
password: string;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
confirm_password: string;
|
|
47
|
+
given_name?: string;
|
|
48
|
+
family_name?: string;
|
|
49
|
+
middle_name?: string;
|
|
50
|
+
picture?: string;
|
|
51
|
+
gender?: string;
|
|
52
|
+
birthdate?: string;
|
|
53
|
+
phone_number?: string;
|
|
54
|
+
roles?: string[];
|
|
40
55
|
};
|
|
41
56
|
|
|
42
|
-
type
|
|
57
|
+
export type MagicLinkLoginInput = {
|
|
58
|
+
email: string;
|
|
59
|
+
roles?: string[];
|
|
60
|
+
};
|
|
43
61
|
|
|
44
|
-
type
|
|
62
|
+
export type VerifyEmailInput = { token: string };
|
|
63
|
+
|
|
64
|
+
export type GraphqlQueryInput = {
|
|
45
65
|
query: string;
|
|
46
66
|
variables?: Record<string, any>;
|
|
47
67
|
headers?: Headers;
|
|
48
68
|
};
|
|
49
69
|
|
|
50
|
-
type MetaData = {
|
|
70
|
+
export type MetaData = {
|
|
51
71
|
version: string;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
is_google_login_enabled: boolean;
|
|
73
|
+
is_facebook_login_enabled: boolean;
|
|
74
|
+
is_github_login_enabled: boolean;
|
|
75
|
+
is_email_verification_enabled: boolean;
|
|
76
|
+
is_basic_authentication_enabled: boolean;
|
|
77
|
+
is_magic_link_login_enabled: boolean;
|
|
58
78
|
};
|
|
59
79
|
|
|
60
|
-
type UpdateProfileInput = {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
firstName?: string;
|
|
65
|
-
lastName?: string;
|
|
66
|
-
image?: string;
|
|
80
|
+
export type UpdateProfileInput = {
|
|
81
|
+
old_password?: string;
|
|
82
|
+
new_password?: string;
|
|
83
|
+
confirm_new_password?: string;
|
|
67
84
|
email?: string;
|
|
85
|
+
given_name?: string;
|
|
86
|
+
family_name?: string;
|
|
87
|
+
middle_name?: string;
|
|
88
|
+
nickname?: string;
|
|
89
|
+
gender?: string;
|
|
90
|
+
birthdate?: string;
|
|
91
|
+
phone_number?: string;
|
|
92
|
+
picture?: string;
|
|
68
93
|
};
|
|
69
94
|
|
|
70
|
-
type ForgotPasswordInput = {
|
|
95
|
+
export type ForgotPasswordInput = {
|
|
71
96
|
email: string;
|
|
72
97
|
};
|
|
73
98
|
|
|
74
|
-
type ResetPasswordInput = {
|
|
99
|
+
export type ResetPasswordInput = {
|
|
75
100
|
token: string;
|
|
76
101
|
password: string;
|
|
77
|
-
|
|
102
|
+
confirm_password: string;
|
|
78
103
|
};
|
|
79
104
|
|
|
80
|
-
enum OAuthProviders {
|
|
105
|
+
export enum OAuthProviders {
|
|
81
106
|
Github = 'github',
|
|
82
107
|
Google = 'google',
|
|
108
|
+
Facebook = 'facebook',
|
|
83
109
|
}
|
|
84
110
|
|
|
85
111
|
const hasWindow = (): boolean => typeof window !== 'undefined';
|
|
86
112
|
|
|
87
113
|
// re-usable gql response fragment
|
|
88
|
-
const
|
|
114
|
+
const userFragment = `id email email_verified given_name family_name middle_name nickname preferred_username picture signup_methods gender birthdate phone_number phone_number_verified roles created_at updated_at `;
|
|
115
|
+
const authTokenFragment = `message access_token expires_at user { ${userFragment} }`;
|
|
116
|
+
|
|
117
|
+
const trimURL = (url: string): string => {
|
|
118
|
+
let trimmedData = url.trim();
|
|
119
|
+
const lastChar = trimmedData[trimmedData.length - 1];
|
|
120
|
+
if (lastChar === '/') {
|
|
121
|
+
trimmedData = trimmedData.slice(0, -1);
|
|
122
|
+
} else {
|
|
123
|
+
trimmedData = trimmedData;
|
|
124
|
+
}
|
|
89
125
|
|
|
90
|
-
|
|
126
|
+
return trimmedData;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export class Authorizer {
|
|
91
130
|
// class variable
|
|
92
131
|
config: ConfigType;
|
|
93
132
|
|
|
@@ -97,20 +136,16 @@ export default class Authorizer {
|
|
|
97
136
|
throw new Error(`Configuration is required`);
|
|
98
137
|
}
|
|
99
138
|
this.config = config;
|
|
100
|
-
if (!config.authorizerURL.trim()) {
|
|
139
|
+
if (!config.authorizerURL && !config.authorizerURL.trim()) {
|
|
101
140
|
throw new Error(`Invalid authorizerURL`);
|
|
102
141
|
}
|
|
103
142
|
if (config.authorizerURL) {
|
|
104
|
-
|
|
105
|
-
const lastChar = trimmedData[trimmedData.length - 1];
|
|
106
|
-
if (lastChar === '/') {
|
|
107
|
-
this.config.authorizerURL = trimmedData.slice(0, -1);
|
|
108
|
-
} else {
|
|
109
|
-
this.config.authorizerURL = trimmedData;
|
|
110
|
-
}
|
|
143
|
+
this.config.authorizerURL = trimURL(config.authorizerURL);
|
|
111
144
|
}
|
|
112
|
-
if (!config.redirectURL) {
|
|
145
|
+
if (!config.redirectURL && !config.redirectURL.trim()) {
|
|
113
146
|
throw new Error(`Invalid redirectURL`);
|
|
147
|
+
} else {
|
|
148
|
+
this.config.redirectURL = trimURL(config.redirectURL);
|
|
114
149
|
}
|
|
115
150
|
}
|
|
116
151
|
|
|
@@ -146,7 +181,7 @@ export default class Authorizer {
|
|
|
146
181
|
getMetaData = async (): Promise<MetaData | void> => {
|
|
147
182
|
try {
|
|
148
183
|
const res = await this.graphqlQuery({
|
|
149
|
-
query: `query { meta { version
|
|
184
|
+
query: `query { meta { version is_google_login_enabled is_facebook_login_enabled is_github_login_enabled is_email_verification_enabled is_basic_authentication_enabled is_magic_link_login_enabled } }`,
|
|
150
185
|
});
|
|
151
186
|
|
|
152
187
|
return res.meta;
|
|
@@ -156,13 +191,34 @@ export default class Authorizer {
|
|
|
156
191
|
};
|
|
157
192
|
|
|
158
193
|
// this is used to verify / get session using cookie by default. If using nodejs pass authorization header
|
|
159
|
-
getSession = async (
|
|
194
|
+
getSession = async (
|
|
195
|
+
headers?: Headers,
|
|
196
|
+
roles?: string[],
|
|
197
|
+
): Promise<AuthToken> => {
|
|
160
198
|
try {
|
|
161
199
|
const res = await this.graphqlQuery({
|
|
162
|
-
query: `query {
|
|
200
|
+
query: `query getSession($roles: [String!]){session(roles: $roles) { ${authTokenFragment} } }`,
|
|
163
201
|
headers,
|
|
202
|
+
variables: {
|
|
203
|
+
roles,
|
|
204
|
+
},
|
|
164
205
|
});
|
|
165
|
-
return res.
|
|
206
|
+
return res.session;
|
|
207
|
+
} catch (err) {
|
|
208
|
+
throw err;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
magicLinkLogin = async (data: MagicLinkLoginInput): Promise<Response> => {
|
|
213
|
+
try {
|
|
214
|
+
const res = await this.graphqlQuery({
|
|
215
|
+
query: `
|
|
216
|
+
mutation magicLinkLogin($data: MagicLinkLoginInput!) { magic_link_login(params: $data) { message }}
|
|
217
|
+
`,
|
|
218
|
+
variables: { data },
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
return res.magic_link_login;
|
|
166
222
|
} catch (err) {
|
|
167
223
|
throw err;
|
|
168
224
|
}
|
|
@@ -172,13 +228,14 @@ export default class Authorizer {
|
|
|
172
228
|
try {
|
|
173
229
|
const res = await this.graphqlQuery({
|
|
174
230
|
query: `
|
|
175
|
-
|
|
231
|
+
mutation signup($data: SignUpInput!) { signup(params: $data) { ${authTokenFragment}}}
|
|
232
|
+
`,
|
|
176
233
|
variables: { data },
|
|
177
234
|
});
|
|
178
235
|
|
|
179
236
|
return res.signup;
|
|
180
237
|
} catch (err) {
|
|
181
|
-
|
|
238
|
+
throw err;
|
|
182
239
|
}
|
|
183
240
|
};
|
|
184
241
|
|
|
@@ -186,13 +243,14 @@ export default class Authorizer {
|
|
|
186
243
|
try {
|
|
187
244
|
const res = await this.graphqlQuery({
|
|
188
245
|
query: `
|
|
189
|
-
|
|
246
|
+
mutation verifyEmail($data: VerifyEmailInput!) { verify_email(params: $data) { ${authTokenFragment}}}
|
|
247
|
+
`,
|
|
190
248
|
variables: { data },
|
|
191
249
|
});
|
|
192
250
|
|
|
193
|
-
return res.
|
|
251
|
+
return res.verify_email;
|
|
194
252
|
} catch (err) {
|
|
195
|
-
|
|
253
|
+
throw err;
|
|
196
254
|
}
|
|
197
255
|
};
|
|
198
256
|
|
|
@@ -200,20 +258,21 @@ export default class Authorizer {
|
|
|
200
258
|
try {
|
|
201
259
|
const res = await this.graphqlQuery({
|
|
202
260
|
query: `
|
|
203
|
-
|
|
261
|
+
mutation login($data: LoginInput!) { login(params: $data) { ${authTokenFragment}}}
|
|
262
|
+
`,
|
|
204
263
|
variables: { data },
|
|
205
264
|
});
|
|
206
265
|
|
|
207
266
|
return res.login;
|
|
208
267
|
} catch (err) {
|
|
209
|
-
|
|
268
|
+
throw err;
|
|
210
269
|
}
|
|
211
270
|
};
|
|
212
271
|
|
|
213
272
|
getProfile = async (headers?: Headers): Promise<User | void> => {
|
|
214
273
|
try {
|
|
215
274
|
const profileRes = await this.graphqlQuery({
|
|
216
|
-
query: `query { profile {
|
|
275
|
+
query: `query { profile { ${userFragment} } }`,
|
|
217
276
|
headers,
|
|
218
277
|
});
|
|
219
278
|
|
|
@@ -229,14 +288,14 @@ export default class Authorizer {
|
|
|
229
288
|
): Promise<Response | void> => {
|
|
230
289
|
try {
|
|
231
290
|
const updateProfileRes = await this.graphqlQuery({
|
|
232
|
-
query: `mutation updateProfile($data: UpdateProfileInput!) {
|
|
291
|
+
query: `mutation updateProfile($data: UpdateProfileInput!) { update_profile(params: $data) { message } }`,
|
|
233
292
|
headers,
|
|
234
293
|
variables: {
|
|
235
294
|
data,
|
|
236
295
|
},
|
|
237
296
|
});
|
|
238
297
|
|
|
239
|
-
return updateProfileRes.
|
|
298
|
+
return updateProfileRes.update_profile;
|
|
240
299
|
} catch (error) {
|
|
241
300
|
throw error;
|
|
242
301
|
}
|
|
@@ -247,13 +306,13 @@ export default class Authorizer {
|
|
|
247
306
|
): Promise<Response | void> => {
|
|
248
307
|
try {
|
|
249
308
|
const forgotPasswordRes = await this.graphqlQuery({
|
|
250
|
-
query: `mutation forgotPassword($data: ForgotPasswordInput!) {
|
|
309
|
+
query: `mutation forgotPassword($data: ForgotPasswordInput!) { forgot_password(params: $data) { message } }`,
|
|
251
310
|
variables: {
|
|
252
311
|
data,
|
|
253
312
|
},
|
|
254
313
|
});
|
|
255
314
|
|
|
256
|
-
return forgotPasswordRes.
|
|
315
|
+
return forgotPasswordRes.forgot_password;
|
|
257
316
|
} catch (error) {
|
|
258
317
|
throw error;
|
|
259
318
|
}
|
|
@@ -264,24 +323,24 @@ export default class Authorizer {
|
|
|
264
323
|
): Promise<Response | void> => {
|
|
265
324
|
try {
|
|
266
325
|
const resetPasswordRes = await this.graphqlQuery({
|
|
267
|
-
query: `mutation resetPassword($data: ResetPasswordInput!) {
|
|
326
|
+
query: `mutation resetPassword($data: ResetPasswordInput!) { reset_password(params: $data) { message } }`,
|
|
268
327
|
variables: {
|
|
269
328
|
data,
|
|
270
329
|
},
|
|
271
330
|
});
|
|
272
|
-
return resetPasswordRes.
|
|
331
|
+
return resetPasswordRes.reset_password;
|
|
273
332
|
} catch (error) {
|
|
274
333
|
throw error;
|
|
275
334
|
}
|
|
276
335
|
};
|
|
277
336
|
|
|
278
|
-
|
|
337
|
+
browserLogin = async (): Promise<AuthToken | void> => {
|
|
279
338
|
try {
|
|
280
339
|
const token = await this.getSession();
|
|
281
340
|
return token;
|
|
282
341
|
} catch (err) {
|
|
283
342
|
if (!hasWindow()) {
|
|
284
|
-
throw new Error(`
|
|
343
|
+
throw new Error(`browserLogin is only supported for browsers`);
|
|
285
344
|
}
|
|
286
345
|
window.location.href = `${this.config.authorizerURL}/app?state=${btoa(
|
|
287
346
|
JSON.stringify(this.config),
|
|
@@ -289,7 +348,10 @@ export default class Authorizer {
|
|
|
289
348
|
}
|
|
290
349
|
};
|
|
291
350
|
|
|
292
|
-
oauthLogin = async (
|
|
351
|
+
oauthLogin = async (
|
|
352
|
+
oauthProvider: string,
|
|
353
|
+
roles?: string[],
|
|
354
|
+
): Promise<void> => {
|
|
293
355
|
// @ts-ignore
|
|
294
356
|
if (!Object.values(OAuthProviders).includes(oauthProvider)) {
|
|
295
357
|
throw new Error(
|
|
@@ -301,7 +363,11 @@ export default class Authorizer {
|
|
|
301
363
|
if (!hasWindow()) {
|
|
302
364
|
throw new Error(`oauthLogin is only supported for browsers`);
|
|
303
365
|
}
|
|
304
|
-
window.location.href = `${
|
|
366
|
+
window.location.href = `${
|
|
367
|
+
this.config.authorizerURL
|
|
368
|
+
}/oauth_login/${oauthProvider}?redirectURL=${
|
|
369
|
+
this.config.redirectURL || window.location.origin
|
|
370
|
+
}${roles && roles.length ? `&roles=${roles.join(',')}` : ``}`;
|
|
305
371
|
};
|
|
306
372
|
|
|
307
373
|
logout = async (headers?: Headers): Promise<Response | void> => {
|
|
@@ -312,6 +378,7 @@ export default class Authorizer {
|
|
|
312
378
|
});
|
|
313
379
|
return res.logout;
|
|
314
380
|
} catch (err) {
|
|
381
|
+
console.log(`logout err:`, err);
|
|
315
382
|
console.error(err);
|
|
316
383
|
}
|
|
317
384
|
};
|