dce-reactkit 3.9.1 → 3.9.3
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/dist/cjs/index.js +100 -26
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/helpers/genRouteHandler.d.ts +8 -0
- package/dist/cjs/types/types/ReactKitErrorCode.d.ts +2 -0
- package/dist/esm/index.js +100 -26
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/helpers/genRouteHandler.d.ts +8 -0
- package/dist/esm/types/types/ReactKitErrorCode.d.ts +2 -0
- package/dist/index.d.ts +10 -0
- package/package.json +1 -1
- package/src/helpers/genRouteHandler.ts +109 -10
- package/src/types/ReactKitErrorCode.tsx +3 -1
|
@@ -9,6 +9,12 @@ import LogFunction from '../types/LogFunction';
|
|
|
9
9
|
* @param opts.handler function that processes the request
|
|
10
10
|
* @param [opts.skipSessionCheck] if true, skip the session check (allow users
|
|
11
11
|
* to not be logged in and launched via LTI)
|
|
12
|
+
* @param [opts.allowedHosts] if included, only allow requests from these hosts
|
|
13
|
+
* (start a hostname with a "*" to only check the end of the hostname)
|
|
14
|
+
* you can include just one string instead of an array
|
|
15
|
+
* @param [opts.bannedHosts] if included, do not allow requests from these hosts
|
|
16
|
+
* (start a hostname with a "*" to only check the end of the hostname)
|
|
17
|
+
* you can include just one string instead of an array
|
|
12
18
|
* @param [opts.unhandledErrorMessagePrefix] if included, when an error that
|
|
13
19
|
* is not of type ErrorWithCode is thrown, the client will receive an error
|
|
14
20
|
* where the error message is prefixed with this string. For example,
|
|
@@ -63,6 +69,8 @@ declare const genRouteHandler: (opts: {
|
|
|
63
69
|
logServerEvent: LogFunction;
|
|
64
70
|
}) => any;
|
|
65
71
|
skipSessionCheck?: boolean | undefined;
|
|
72
|
+
allowedHosts?: string | string[] | undefined;
|
|
73
|
+
bannedHosts?: string | string[] | undefined;
|
|
66
74
|
unhandledErrorMessagePrefix?: string | undefined;
|
|
67
75
|
}) => (req: any, res: any, next: () => void) => Promise<undefined>;
|
|
68
76
|
export default genRouteHandler;
|
|
@@ -8,6 +8,8 @@ declare enum ReactKitErrorCode {
|
|
|
8
8
|
SessionExpired = "DRK3",
|
|
9
9
|
MissingParameter = "DRK4",
|
|
10
10
|
InvalidParameter = "DRK5",
|
|
11
|
+
HostNotAllowed = "DRK17",
|
|
12
|
+
HostBanned = "DRK18",
|
|
11
13
|
WrongCourse = "DRK6",
|
|
12
14
|
NoCACCLSendRequestFunction = "DRK7",
|
|
13
15
|
NoCACCLGetLaunchInfoFunction = "DRK8",
|
package/dist/index.d.ts
CHANGED
|
@@ -1044,6 +1044,12 @@ type LogFunction = (opts: ({
|
|
|
1044
1044
|
* @param opts.handler function that processes the request
|
|
1045
1045
|
* @param [opts.skipSessionCheck] if true, skip the session check (allow users
|
|
1046
1046
|
* to not be logged in and launched via LTI)
|
|
1047
|
+
* @param [opts.allowedHosts] if included, only allow requests from these hosts
|
|
1048
|
+
* (start a hostname with a "*" to only check the end of the hostname)
|
|
1049
|
+
* you can include just one string instead of an array
|
|
1050
|
+
* @param [opts.bannedHosts] if included, do not allow requests from these hosts
|
|
1051
|
+
* (start a hostname with a "*" to only check the end of the hostname)
|
|
1052
|
+
* you can include just one string instead of an array
|
|
1047
1053
|
* @param [opts.unhandledErrorMessagePrefix] if included, when an error that
|
|
1048
1054
|
* is not of type ErrorWithCode is thrown, the client will receive an error
|
|
1049
1055
|
* where the error message is prefixed with this string. For example,
|
|
@@ -1098,6 +1104,8 @@ declare const genRouteHandler: (opts: {
|
|
|
1098
1104
|
logServerEvent: LogFunction;
|
|
1099
1105
|
}) => any;
|
|
1100
1106
|
skipSessionCheck?: boolean | undefined;
|
|
1107
|
+
allowedHosts?: string | string[] | undefined;
|
|
1108
|
+
bannedHosts?: string | string[] | undefined;
|
|
1101
1109
|
unhandledErrorMessagePrefix?: string | undefined;
|
|
1102
1110
|
}) => (req: any, res: any, next: () => void) => Promise<undefined>;
|
|
1103
1111
|
|
|
@@ -1637,6 +1645,8 @@ declare enum ReactKitErrorCode {
|
|
|
1637
1645
|
SessionExpired = "DRK3",
|
|
1638
1646
|
MissingParameter = "DRK4",
|
|
1639
1647
|
InvalidParameter = "DRK5",
|
|
1648
|
+
HostNotAllowed = "DRK17",
|
|
1649
|
+
HostBanned = "DRK18",
|
|
1640
1650
|
WrongCourse = "DRK6",
|
|
1641
1651
|
NoCACCLSendRequestFunction = "DRK7",
|
|
1642
1652
|
NoCACCLGetLaunchInfoFunction = "DRK8",
|
package/package.json
CHANGED
|
@@ -39,6 +39,12 @@ import LogLevel from '../types/LogLevel';
|
|
|
39
39
|
* @param opts.handler function that processes the request
|
|
40
40
|
* @param [opts.skipSessionCheck] if true, skip the session check (allow users
|
|
41
41
|
* to not be logged in and launched via LTI)
|
|
42
|
+
* @param [opts.allowedHosts] if included, only allow requests from these hosts
|
|
43
|
+
* (start a hostname with a "*" to only check the end of the hostname)
|
|
44
|
+
* you can include just one string instead of an array
|
|
45
|
+
* @param [opts.bannedHosts] if included, do not allow requests from these hosts
|
|
46
|
+
* (start a hostname with a "*" to only check the end of the hostname)
|
|
47
|
+
* you can include just one string instead of an array
|
|
42
48
|
* @param [opts.unhandledErrorMessagePrefix] if included, when an error that
|
|
43
49
|
* is not of type ErrorWithCode is thrown, the client will receive an error
|
|
44
50
|
* where the error message is prefixed with this string. For example,
|
|
@@ -102,6 +108,8 @@ const genRouteHandler = (
|
|
|
102
108
|
},
|
|
103
109
|
) => any,
|
|
104
110
|
skipSessionCheck?: boolean,
|
|
111
|
+
allowedHosts?: string[] | string,
|
|
112
|
+
bannedHosts?: string[] | string,
|
|
105
113
|
unhandledErrorMessagePrefix?: string,
|
|
106
114
|
},
|
|
107
115
|
) => {
|
|
@@ -110,6 +118,97 @@ const genRouteHandler = (
|
|
|
110
118
|
// Output params
|
|
111
119
|
const output: { [k in string]: any } = {};
|
|
112
120
|
|
|
121
|
+
/*----------------------------------------*/
|
|
122
|
+
/* ----------- Hostname Check ----------- */
|
|
123
|
+
/*----------------------------------------*/
|
|
124
|
+
|
|
125
|
+
// Get hostnames
|
|
126
|
+
const originURL = String(
|
|
127
|
+
req.get('origin')
|
|
128
|
+
|| req.headers.origin
|
|
129
|
+
|| req.headers.referer
|
|
130
|
+
);
|
|
131
|
+
const originHostname = (
|
|
132
|
+
originURL
|
|
133
|
+
// Remove protocol
|
|
134
|
+
.replace(/(^\w+:|^)\/\//, '')
|
|
135
|
+
// Remove port
|
|
136
|
+
.replace(/:\d+$/, '')
|
|
137
|
+
);
|
|
138
|
+
const serverHostname = String(req.hostname);
|
|
139
|
+
|
|
140
|
+
// Check allowed
|
|
141
|
+
if (opts.allowedHosts) {
|
|
142
|
+
// Only accept requests from allowed hosts
|
|
143
|
+
const allowedArray = (
|
|
144
|
+
Array.isArray(opts.allowedHosts)
|
|
145
|
+
? opts.allowedHosts
|
|
146
|
+
: [opts.allowedHosts]
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// Check if server is localhost
|
|
150
|
+
if (serverHostname === 'localhost') {
|
|
151
|
+
// Allow localhost
|
|
152
|
+
allowedArray.push('localhost');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Check if current host is allowed
|
|
156
|
+
const allowed = allowedArray.some((allowedHost) => {
|
|
157
|
+
if (allowedHost.startsWith('*')) {
|
|
158
|
+
// Check end of hostname
|
|
159
|
+
return originHostname.endsWith(allowedHost.substring(1));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Check full hostname
|
|
163
|
+
return originHostname.toLowerCase() === allowedHost.toLowerCase();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// If not allowed, return error
|
|
167
|
+
if (!allowed) {
|
|
168
|
+
return handleError(
|
|
169
|
+
res,
|
|
170
|
+
{
|
|
171
|
+
message: 'You are not allowed to access this endpoint.',
|
|
172
|
+
code: ReactKitErrorCode.HostNotAllowed,
|
|
173
|
+
status: 403,
|
|
174
|
+
},
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Check banned
|
|
180
|
+
if (opts.bannedHosts) {
|
|
181
|
+
// Do not allow requests from banned hosts
|
|
182
|
+
const bannedArray = (
|
|
183
|
+
Array.isArray(opts.bannedHosts)
|
|
184
|
+
? opts.bannedHosts
|
|
185
|
+
: [opts.bannedHosts]
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// Check if current host is banned
|
|
189
|
+
const banned = bannedArray.some((bannedHost) => {
|
|
190
|
+
if (bannedHost.startsWith('*')) {
|
|
191
|
+
// Check end of hostname
|
|
192
|
+
return originHostname.endsWith(bannedHost.substring(1));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Check full hostname
|
|
196
|
+
return originHostname.toLowerCase() === bannedHost.toLowerCase();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// If banned, return error
|
|
200
|
+
if (banned) {
|
|
201
|
+
return handleError(
|
|
202
|
+
res,
|
|
203
|
+
{
|
|
204
|
+
message: 'You are not allowed to access this endpoint.',
|
|
205
|
+
code: ReactKitErrorCode.HostBanned,
|
|
206
|
+
status: 403,
|
|
207
|
+
},
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
113
212
|
/*----------------------------------------*/
|
|
114
213
|
/* ------------ Parse Params ------------ */
|
|
115
214
|
/*----------------------------------------*/
|
|
@@ -354,22 +453,22 @@ const genRouteHandler = (
|
|
|
354
453
|
output.userId = (
|
|
355
454
|
launchInfo
|
|
356
455
|
? launchInfo.userId
|
|
357
|
-
: undefined
|
|
456
|
+
: (output.userId ?? undefined)
|
|
358
457
|
);
|
|
359
458
|
output.userFirstName = (
|
|
360
459
|
launchInfo
|
|
361
460
|
? launchInfo.userFirstName
|
|
362
|
-
: undefined
|
|
461
|
+
: (output.userFirstName ?? undefined)
|
|
363
462
|
);
|
|
364
463
|
output.userLastName = (
|
|
365
464
|
launchInfo
|
|
366
465
|
? launchInfo.userLastName
|
|
367
|
-
: undefined
|
|
466
|
+
: (output.userLastName ?? undefined)
|
|
368
467
|
);
|
|
369
468
|
output.userEmail = (
|
|
370
469
|
launchInfo
|
|
371
470
|
? launchInfo.userEmail
|
|
372
|
-
: undefined
|
|
471
|
+
: (output.userEmail ?? undefined)
|
|
373
472
|
);
|
|
374
473
|
output.userAvatarURL = (
|
|
375
474
|
launchInfo
|
|
@@ -377,32 +476,32 @@ const genRouteHandler = (
|
|
|
377
476
|
launchInfo.userImage
|
|
378
477
|
?? 'http://www.gravatar.com/avatar/?d=identicon'
|
|
379
478
|
)
|
|
380
|
-
: undefined
|
|
479
|
+
: (output.userAvatarURL ?? undefined)
|
|
381
480
|
);
|
|
382
481
|
output.isLearner = (
|
|
383
482
|
launchInfo
|
|
384
483
|
? !!launchInfo.isLearner
|
|
385
|
-
: undefined
|
|
484
|
+
: (output.isLearner ?? undefined)
|
|
386
485
|
);
|
|
387
486
|
output.isTTM = (
|
|
388
487
|
launchInfo
|
|
389
488
|
? !!launchInfo.isTTM
|
|
390
|
-
: undefined
|
|
489
|
+
: (output.isTTM ?? undefined)
|
|
391
490
|
);
|
|
392
491
|
output.isAdmin = (
|
|
393
492
|
launchInfo
|
|
394
493
|
? !!launchInfo.isAdmin
|
|
395
|
-
: undefined
|
|
494
|
+
: (output.isAdmin ?? undefined)
|
|
396
495
|
);
|
|
397
496
|
output.courseId = (
|
|
398
497
|
launchInfo
|
|
399
498
|
? (output.courseId ?? launchInfo.courseId)
|
|
400
|
-
: undefined
|
|
499
|
+
: (output.courseId ?? undefined)
|
|
401
500
|
);
|
|
402
501
|
output.courseName = (
|
|
403
502
|
launchInfo
|
|
404
503
|
? launchInfo.contextLabel
|
|
405
|
-
: undefined
|
|
504
|
+
: (output.courseName ?? undefined)
|
|
406
505
|
);
|
|
407
506
|
|
|
408
507
|
// Add other session variables
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Highest error code =
|
|
1
|
+
// Highest error code = DRK18
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* List of error codes built into the react kit
|
|
@@ -10,6 +10,8 @@ enum ReactKitErrorCode {
|
|
|
10
10
|
SessionExpired = 'DRK3',
|
|
11
11
|
MissingParameter = 'DRK4',
|
|
12
12
|
InvalidParameter = 'DRK5',
|
|
13
|
+
HostNotAllowed = 'DRK17',
|
|
14
|
+
HostBanned = 'DRK18',
|
|
13
15
|
WrongCourse = 'DRK6',
|
|
14
16
|
NoCACCLSendRequestFunction = 'DRK7',
|
|
15
17
|
NoCACCLGetLaunchInfoFunction = 'DRK8',
|