@lti-tool/core 0.13.1 → 0.14.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/CHANGELOG.md +12 -0
- package/dist/ltiTool.d.ts.map +1 -1
- package/dist/ltiTool.js +296 -133
- package/dist/schemas/lti13/dynamicRegistration/ltiMessages.schema.d.ts +15 -9
- package/dist/schemas/lti13/dynamicRegistration/ltiMessages.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/dynamicRegistration/ltiMessages.schema.js +7 -1
- package/dist/schemas/lti13/dynamicRegistration/registrationResponse.schema.d.ts +5 -3
- package/dist/schemas/lti13/dynamicRegistration/registrationResponse.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.d.ts +10 -6
- package/dist/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.d.ts.map +1 -1
- package/dist/services/dynamicRegistration.service.d.ts +12 -0
- package/dist/services/dynamicRegistration.service.d.ts.map +1 -1
- package/dist/services/dynamicRegistration.service.js +68 -11
- package/dist/services/dynamicRegistrationHandlers/moodle.js +1 -1
- package/dist/utils/errorFormatting.d.ts +18 -0
- package/dist/utils/errorFormatting.d.ts.map +1 -0
- package/dist/utils/errorFormatting.js +22 -0
- package/package.json +1 -1
- package/src/ltiTool.ts +364 -165
- package/src/schemas/lti13/dynamicRegistration/ltiMessages.schema.ts +9 -1
- package/src/services/dynamicRegistration.service.ts +85 -10
- package/src/services/dynamicRegistrationHandlers/moodle.ts +1 -1
- package/src/utils/errorFormatting.ts +22 -0
|
@@ -26,9 +26,11 @@ declare const LTIDeepLinkingMessageSchema: z.ZodObject<{
|
|
|
26
26
|
target_link_uri: z.ZodOptional<z.ZodURL>;
|
|
27
27
|
label: z.ZodOptional<z.ZodString>;
|
|
28
28
|
placements: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
editor_button: "editor_button";
|
|
30
|
+
assignment_selection: "assignment_selection";
|
|
31
|
+
link_selection: "link_selection";
|
|
32
|
+
module_index_menu_modal: "module_index_menu_modal";
|
|
33
|
+
module_menu_modal: "module_menu_modal";
|
|
32
34
|
}>>>;
|
|
33
35
|
supported_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
34
36
|
file: "file";
|
|
@@ -53,9 +55,11 @@ export declare const LTIMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
53
55
|
target_link_uri: z.ZodOptional<z.ZodURL>;
|
|
54
56
|
label: z.ZodOptional<z.ZodString>;
|
|
55
57
|
placements: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
editor_button: "editor_button";
|
|
59
|
+
assignment_selection: "assignment_selection";
|
|
60
|
+
link_selection: "link_selection";
|
|
61
|
+
module_index_menu_modal: "module_index_menu_modal";
|
|
62
|
+
module_menu_modal: "module_menu_modal";
|
|
59
63
|
}>>>;
|
|
60
64
|
supported_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
61
65
|
file: "file";
|
|
@@ -79,9 +83,11 @@ export declare const LTIMessagesArraySchema: z.ZodArray<z.ZodDiscriminatedUnion<
|
|
|
79
83
|
target_link_uri: z.ZodOptional<z.ZodURL>;
|
|
80
84
|
label: z.ZodOptional<z.ZodString>;
|
|
81
85
|
placements: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
editor_button: "editor_button";
|
|
87
|
+
assignment_selection: "assignment_selection";
|
|
88
|
+
link_selection: "link_selection";
|
|
89
|
+
module_index_menu_modal: "module_index_menu_modal";
|
|
90
|
+
module_menu_modal: "module_menu_modal";
|
|
85
91
|
}>>>;
|
|
86
92
|
supported_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
87
93
|
file: "file";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ltiMessages.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/dynamicRegistration/ltiMessages.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB;;;;GAIG;AACH,QAAA,MAAM,4BAA4B;;iBAEhC,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,2BAA2B
|
|
1
|
+
{"version":3,"file":"ltiMessages.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/dynamicRegistration/ltiMessages.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB;;;;GAIG;AACH,QAAA,MAAM,4BAA4B;;iBAEhC,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;iBAqB/B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;2BAG3B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;4BAA4B,CAAC;AAEhE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAClF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
|
|
@@ -26,7 +26,13 @@ const LTIDeepLinkingMessageSchema = z.object({
|
|
|
26
26
|
target_link_uri: z.url().optional(),
|
|
27
27
|
label: z.string().optional(),
|
|
28
28
|
placements: z
|
|
29
|
-
.array(z.enum([
|
|
29
|
+
.array(z.enum([
|
|
30
|
+
'editor_button',
|
|
31
|
+
'assignment_selection',
|
|
32
|
+
'link_selection',
|
|
33
|
+
'module_index_menu_modal',
|
|
34
|
+
'module_menu_modal',
|
|
35
|
+
]))
|
|
30
36
|
.optional(),
|
|
31
37
|
supported_types: z
|
|
32
38
|
.array(z.enum(['ltiResourceLink', 'file', 'html', 'link', 'image']))
|
|
@@ -50,9 +50,11 @@ export declare const RegistrationResponseSchema: z.ZodObject<{
|
|
|
50
50
|
target_link_uri: z.ZodOptional<z.ZodURL>;
|
|
51
51
|
label: z.ZodOptional<z.ZodString>;
|
|
52
52
|
placements: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
editor_button: "editor_button";
|
|
54
|
+
assignment_selection: "assignment_selection";
|
|
55
|
+
link_selection: "link_selection";
|
|
56
|
+
module_index_menu_modal: "module_index_menu_modal";
|
|
57
|
+
module_menu_modal: "module_menu_modal";
|
|
56
58
|
}>>>;
|
|
57
59
|
supported_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
58
60
|
file: "file";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registrationResponse.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/dynamicRegistration/registrationResponse.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AA0BzB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,0BAA0B
|
|
1
|
+
{"version":3,"file":"registrationResponse.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/dynamicRegistration/registrationResponse.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AA0BzB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiBrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
|
|
@@ -21,9 +21,11 @@ declare const LTIToolConfigurationSchema: z.ZodObject<{
|
|
|
21
21
|
target_link_uri: z.ZodOptional<z.ZodURL>;
|
|
22
22
|
label: z.ZodOptional<z.ZodString>;
|
|
23
23
|
placements: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
editor_button: "editor_button";
|
|
25
|
+
assignment_selection: "assignment_selection";
|
|
26
|
+
link_selection: "link_selection";
|
|
27
|
+
module_index_menu_modal: "module_index_menu_modal";
|
|
28
|
+
module_menu_modal: "module_menu_modal";
|
|
27
29
|
}>>>;
|
|
28
30
|
supported_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
29
31
|
file: "file";
|
|
@@ -80,9 +82,11 @@ export declare const ToolRegistrationPayloadSchema: z.ZodObject<{
|
|
|
80
82
|
target_link_uri: z.ZodOptional<z.ZodURL>;
|
|
81
83
|
label: z.ZodOptional<z.ZodString>;
|
|
82
84
|
placements: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
editor_button: "editor_button";
|
|
86
|
+
assignment_selection: "assignment_selection";
|
|
87
|
+
link_selection: "link_selection";
|
|
88
|
+
module_index_menu_modal: "module_index_menu_modal";
|
|
89
|
+
module_menu_modal: "module_menu_modal";
|
|
86
90
|
}>>>;
|
|
87
91
|
supported_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
88
92
|
file: "file";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolRegistrationPayload.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAIzB;;;;;;;;;GASG;AACH,QAAA,MAAM,0BAA0B
|
|
1
|
+
{"version":3,"file":"toolRegistrationPayload.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAIzB;;;;;;;;;GASG;AACH,QAAA,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAM9B,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAYxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AACpF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
|
|
@@ -97,12 +97,23 @@ export declare class DynamicRegistrationService {
|
|
|
97
97
|
* @returns Session data if valid and not expired, undefined otherwise
|
|
98
98
|
*/
|
|
99
99
|
verifyRegistrationSession(sessionToken: string): Promise<LTIDynamicRegistrationSession | undefined>;
|
|
100
|
+
/**
|
|
101
|
+
* Builds Canvas-specific deep linking messages for the 5 common placements.
|
|
102
|
+
* Creates separate messages for editor, module menu, assignments, modules page, and link selection.
|
|
103
|
+
*
|
|
104
|
+
* @param deepLinkingUri - URI where deep linking requests should be sent
|
|
105
|
+
* @param toolName - Display name of the tool
|
|
106
|
+
* @returns Array of Canvas deep linking message configurations
|
|
107
|
+
*/
|
|
108
|
+
private buildCanvasDeepLinkingMessages;
|
|
100
109
|
/**
|
|
101
110
|
* Builds array of LTI message types based on selected services during registration.
|
|
102
111
|
* Always includes ResourceLinkRequest, conditionally adds DeepLinkingRequest.
|
|
103
112
|
*
|
|
104
113
|
* @param selectedServices - Array of service names selected by administrator
|
|
105
114
|
* @param deepLinkingUri - URI where deep linking requests should be sent
|
|
115
|
+
* @param platformFamily - Platform family code (e.g., 'canvas', 'moodle')
|
|
116
|
+
* @param toolName - Display name of the tool
|
|
106
117
|
* @returns Array of LTI message configurations for the registration payload
|
|
107
118
|
*/
|
|
108
119
|
private buildMessages;
|
|
@@ -119,6 +130,7 @@ export declare class DynamicRegistrationService {
|
|
|
119
130
|
* Combines tool configuration, selected services, and OAuth parameters into LTI 1.3 registration format.
|
|
120
131
|
*
|
|
121
132
|
* @param selectedServices - Array of service names selected by administrator
|
|
133
|
+
* @param platformFamily - Platform family code (e.g., 'canvas', 'moodle')
|
|
122
134
|
* @returns Complete registration payload ready for platform submission
|
|
123
135
|
*/
|
|
124
136
|
private buildRegistrationPayload;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamicRegistration.service.d.ts","sourceRoot":"","sources":["../../src/services/dynamicRegistration.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gDAAgD,CAAC;AACpG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uEAAuE,CAAC;AAErH,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,oEAAoE,CAAC;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oEAAoE,CAAC;AAS9G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,qBAAa,0BAA0B;IASnC,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,yBAAyB;IACjC,OAAO,CAAC,MAAM;IAVhB;;;;;;OAMG;gBAEO,OAAO,EAAE,UAAU,EACnB,yBAAyB,EAAE,yBAAyB,EACpD,MAAM,EAAE,UAAU;IAG5B;;;;;;;OAOG;IACG,0BAA0B,CAC9B,mBAAmB,EAAE,mBAAmB,GACvC,OAAO,CAAC,mBAAmB,CAAC;IAkC/B;;;;;;;;OAQG;IACG,2BAA2B,CAC/B,mBAAmB,EAAE,mBAAmB,EACxC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC;IAsClB;;;;;;;OAOG;IACG,2BAA2B,CAC/B,uBAAuB,EAAE,uBAAuB,GAC/C,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"dynamicRegistration.service.d.ts","sourceRoot":"","sources":["../../src/services/dynamicRegistration.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gDAAgD,CAAC;AACpG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uEAAuE,CAAC;AAErH,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,oEAAoE,CAAC;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oEAAoE,CAAC;AAS9G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,qBAAa,0BAA0B;IASnC,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,yBAAyB;IACjC,OAAO,CAAC,MAAM;IAVhB;;;;;;OAMG;gBAEO,OAAO,EAAE,UAAU,EACnB,yBAAyB,EAAE,yBAAyB,EACpD,MAAM,EAAE,UAAU;IAG5B;;;;;;;OAOG;IACG,0BAA0B,CAC9B,mBAAmB,EAAE,mBAAmB,GACvC,OAAO,CAAC,mBAAmB,CAAC;IAkC/B;;;;;;;;OAQG;IACG,2BAA2B,CAC/B,mBAAmB,EAAE,mBAAmB,EACxC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC;IAsClB;;;;;;;OAOG;IACG,2BAA2B,CAC/B,uBAAuB,EAAE,uBAAuB,GAC/C,OAAO,CAAC,MAAM,CAAC;IA2DlB;;;;;;OAMG;IACG,yBAAyB,CAC7B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,6BAA6B,GAAG,SAAS,CAAC;IAQrD;;;;;;;OAOG;IACH,OAAO,CAAC,8BAA8B;IA2CtC;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa;IA0BrB;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;IAoBnB;;;;;;;OAOG;IACH,OAAO,CAAC,wBAAwB;YA0ClB,mCAAmC;IAgBjD,OAAO,CAAC,0BAA0B;CAiDnC"}
|
|
@@ -140,8 +140,10 @@ export class DynamicRegistrationService {
|
|
|
140
140
|
if (!session) {
|
|
141
141
|
throw new Error('Invalid or expired session');
|
|
142
142
|
}
|
|
143
|
+
// Extract platform family from session
|
|
144
|
+
const platformFamily = session.openIdConfiguration['https://purl.imsglobal.org/spec/lti-platform-configuration'].product_family_code;
|
|
143
145
|
// 1. build payload
|
|
144
|
-
const toolRegistrationPayload = this.buildRegistrationPayload(dynamicRegistrationForm.services ?? []);
|
|
146
|
+
const toolRegistrationPayload = this.buildRegistrationPayload(dynamicRegistrationForm.services ?? [], platformFamily);
|
|
145
147
|
// 2. Post request to Moodle
|
|
146
148
|
const registrationResponse = await postRegistrationToMoodle(session.openIdConfiguration.registration_endpoint, toolRegistrationPayload, this.logger, session.registrationToken);
|
|
147
149
|
// 3. save to storage
|
|
@@ -185,25 +187,79 @@ export class DynamicRegistrationService {
|
|
|
185
187
|
}
|
|
186
188
|
return session;
|
|
187
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Builds Canvas-specific deep linking messages for the 5 common placements.
|
|
192
|
+
* Creates separate messages for editor, module menu, assignments, modules page, and link selection.
|
|
193
|
+
*
|
|
194
|
+
* @param deepLinkingUri - URI where deep linking requests should be sent
|
|
195
|
+
* @param toolName - Display name of the tool
|
|
196
|
+
* @returns Array of Canvas deep linking message configurations
|
|
197
|
+
*/
|
|
198
|
+
buildCanvasDeepLinkingMessages(deepLinkingUri, toolName) {
|
|
199
|
+
return [
|
|
200
|
+
{
|
|
201
|
+
type: 'LtiDeepLinkingRequest',
|
|
202
|
+
target_link_uri: deepLinkingUri,
|
|
203
|
+
label: toolName,
|
|
204
|
+
placements: ['editor_button'],
|
|
205
|
+
supported_types: ['ltiResourceLink'],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
type: 'LtiDeepLinkingRequest',
|
|
209
|
+
target_link_uri: deepLinkingUri,
|
|
210
|
+
label: toolName,
|
|
211
|
+
placements: ['module_menu_modal'],
|
|
212
|
+
supported_types: ['ltiResourceLink'],
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
type: 'LtiDeepLinkingRequest',
|
|
216
|
+
target_link_uri: deepLinkingUri,
|
|
217
|
+
label: toolName,
|
|
218
|
+
placements: ['assignment_selection'],
|
|
219
|
+
supported_types: ['ltiResourceLink'],
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
type: 'LtiDeepLinkingRequest',
|
|
223
|
+
target_link_uri: deepLinkingUri,
|
|
224
|
+
label: toolName,
|
|
225
|
+
placements: ['module_index_menu_modal'],
|
|
226
|
+
supported_types: ['ltiResourceLink'],
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
type: 'LtiDeepLinkingRequest',
|
|
230
|
+
target_link_uri: deepLinkingUri,
|
|
231
|
+
label: toolName,
|
|
232
|
+
placements: ['link_selection'],
|
|
233
|
+
supported_types: ['ltiResourceLink'],
|
|
234
|
+
},
|
|
235
|
+
];
|
|
236
|
+
}
|
|
188
237
|
/**
|
|
189
238
|
* Builds array of LTI message types based on selected services during registration.
|
|
190
239
|
* Always includes ResourceLinkRequest, conditionally adds DeepLinkingRequest.
|
|
191
240
|
*
|
|
192
241
|
* @param selectedServices - Array of service names selected by administrator
|
|
193
242
|
* @param deepLinkingUri - URI where deep linking requests should be sent
|
|
243
|
+
* @param platformFamily - Platform family code (e.g., 'canvas', 'moodle')
|
|
244
|
+
* @param toolName - Display name of the tool
|
|
194
245
|
* @returns Array of LTI message configurations for the registration payload
|
|
195
246
|
*/
|
|
196
|
-
buildMessages(selectedServices, deepLinkingUri) {
|
|
247
|
+
buildMessages(selectedServices, deepLinkingUri, platformFamily, toolName) {
|
|
197
248
|
const messages = [];
|
|
198
249
|
messages.push({ type: 'LtiResourceLinkRequest' });
|
|
199
250
|
if (selectedServices?.includes('deep_linking')) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
251
|
+
if (platformFamily.toLowerCase() === 'canvas') {
|
|
252
|
+
messages.push(...this.buildCanvasDeepLinkingMessages(deepLinkingUri, toolName));
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
messages.push({
|
|
256
|
+
type: 'LtiDeepLinkingRequest',
|
|
257
|
+
target_link_uri: deepLinkingUri,
|
|
258
|
+
label: toolName,
|
|
259
|
+
placements: ['editor_button'],
|
|
260
|
+
supported_types: ['ltiResourceLink'],
|
|
261
|
+
});
|
|
262
|
+
}
|
|
207
263
|
}
|
|
208
264
|
return messages;
|
|
209
265
|
}
|
|
@@ -229,15 +285,16 @@ export class DynamicRegistrationService {
|
|
|
229
285
|
* Combines tool configuration, selected services, and OAuth parameters into LTI 1.3 registration format.
|
|
230
286
|
*
|
|
231
287
|
* @param selectedServices - Array of service names selected by administrator
|
|
288
|
+
* @param platformFamily - Platform family code (e.g., 'canvas', 'moodle')
|
|
232
289
|
* @returns Complete registration payload ready for platform submission
|
|
233
290
|
*/
|
|
234
|
-
buildRegistrationPayload(selectedServices) {
|
|
291
|
+
buildRegistrationPayload(selectedServices, platformFamily) {
|
|
235
292
|
const config = this.dynamicRegistrationConfig;
|
|
236
293
|
const deepLinkingUri = config.deepLinkingUri || `${config.url}/lti/deep-linking`;
|
|
237
294
|
const jwksUri = config.jwksUri || `${config.url}/lti/jwks`;
|
|
238
295
|
const launchUri = config.launchUri || `${config.url}/lti/launch`;
|
|
239
296
|
const loginUri = config.loginUri || `${config.url}/lti/login`;
|
|
240
|
-
const messages = this.buildMessages(selectedServices, deepLinkingUri);
|
|
297
|
+
const messages = this.buildMessages(selectedServices, deepLinkingUri, platformFamily, config.name);
|
|
241
298
|
const scopes = this.buildScopes(selectedServices);
|
|
242
299
|
const toolRegistrationPayload = {
|
|
243
300
|
application_type: 'web',
|
|
@@ -142,7 +142,7 @@ export async function postRegistrationToMoodle(registrationEndpoint, registratio
|
|
|
142
142
|
if (!response.ok) {
|
|
143
143
|
const errorText = await response.json();
|
|
144
144
|
logger.error({ errorText }, 'lti dynamic registration error');
|
|
145
|
-
throw new Error(errorText);
|
|
145
|
+
throw new Error(JSON.stringify(errorText));
|
|
146
146
|
}
|
|
147
147
|
const data = await response.json();
|
|
148
148
|
logger.debug({ data }, 'Registration response');
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats an unknown error into a readable string message.
|
|
3
|
+
* Handles Error objects, strings, and other types safely.
|
|
4
|
+
*
|
|
5
|
+
* @param error - The error to format (can be Error, string, or any other type)
|
|
6
|
+
* @returns Formatted error message string
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* try {
|
|
11
|
+
* await riskyOperation();
|
|
12
|
+
* } catch (error) {
|
|
13
|
+
* throw new Error(`Operation failed: ${formatError(error)}`);
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatError(error: unknown): string;
|
|
18
|
+
//# sourceMappingURL=errorFormatting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorFormatting.d.ts","sourceRoot":"","sources":["../../src/utils/errorFormatting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKlD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats an unknown error into a readable string message.
|
|
3
|
+
* Handles Error objects, strings, and other types safely.
|
|
4
|
+
*
|
|
5
|
+
* @param error - The error to format (can be Error, string, or any other type)
|
|
6
|
+
* @returns Formatted error message string
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* try {
|
|
11
|
+
* await riskyOperation();
|
|
12
|
+
* } catch (error) {
|
|
13
|
+
* throw new Error(`Operation failed: ${formatError(error)}`);
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export function formatError(error) {
|
|
18
|
+
if (error instanceof Error) {
|
|
19
|
+
return error.message;
|
|
20
|
+
}
|
|
21
|
+
return String(error);
|
|
22
|
+
}
|