@lti-tool/core 0.11.0 → 0.12.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/interfaces/index.d.ts +1 -0
  3. package/dist/interfaces/index.d.ts.map +1 -1
  4. package/dist/interfaces/ltiConfig.d.ts +23 -0
  5. package/dist/interfaces/ltiConfig.d.ts.map +1 -1
  6. package/dist/interfaces/ltiDynamicRegistrationSession.d.ts +14 -0
  7. package/dist/interfaces/ltiDynamicRegistrationSession.d.ts.map +1 -0
  8. package/dist/interfaces/ltiDynamicRegistrationSession.js +1 -0
  9. package/dist/interfaces/ltiStorage.d.ts +22 -0
  10. package/dist/interfaces/ltiStorage.d.ts.map +1 -1
  11. package/dist/ltiTool.d.ts +64 -1
  12. package/dist/ltiTool.d.ts.map +1 -1
  13. package/dist/ltiTool.js +87 -1
  14. package/dist/schemas/index.d.ts +5 -0
  15. package/dist/schemas/index.d.ts.map +1 -1
  16. package/dist/schemas/index.js +4 -0
  17. package/dist/schemas/lti13/dynamicRegistration/ltiDynamicRegistration.schema.d.ts +34 -0
  18. package/dist/schemas/lti13/dynamicRegistration/ltiDynamicRegistration.schema.d.ts.map +1 -0
  19. package/dist/schemas/lti13/dynamicRegistration/ltiDynamicRegistration.schema.js +28 -0
  20. package/dist/schemas/lti13/dynamicRegistration/ltiMessages.schema.d.ts +101 -0
  21. package/dist/schemas/lti13/dynamicRegistration/ltiMessages.schema.d.ts.map +1 -0
  22. package/dist/schemas/lti13/dynamicRegistration/ltiMessages.schema.js +51 -0
  23. package/dist/schemas/lti13/dynamicRegistration/openIDConfiguration.schema.d.ts +59 -0
  24. package/dist/schemas/lti13/dynamicRegistration/openIDConfiguration.schema.d.ts.map +1 -0
  25. package/dist/schemas/lti13/dynamicRegistration/openIDConfiguration.schema.js +53 -0
  26. package/dist/schemas/lti13/dynamicRegistration/registrationRequest.schema.d.ts +7 -0
  27. package/dist/schemas/lti13/dynamicRegistration/registrationRequest.schema.d.ts.map +1 -0
  28. package/dist/schemas/lti13/dynamicRegistration/registrationRequest.schema.js +5 -0
  29. package/dist/schemas/lti13/dynamicRegistration/registrationResponse.schema.d.ts +73 -0
  30. package/dist/schemas/lti13/dynamicRegistration/registrationResponse.schema.d.ts.map +1 -0
  31. package/dist/schemas/lti13/dynamicRegistration/registrationResponse.schema.js +61 -0
  32. package/dist/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.d.ts +103 -0
  33. package/dist/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.d.ts.map +1 -0
  34. package/dist/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.js +49 -0
  35. package/dist/services/dynamicRegistration.service.d.ts +121 -0
  36. package/dist/services/dynamicRegistration.service.d.ts.map +1 -0
  37. package/dist/services/dynamicRegistration.service.js +312 -0
  38. package/dist/services/dynamicRegistrationHandlers/moodle.d.ts +48 -0
  39. package/dist/services/dynamicRegistrationHandlers/moodle.d.ts.map +1 -0
  40. package/dist/services/dynamicRegistrationHandlers/moodle.js +152 -0
  41. package/dist/utils/ltiPlatformCapabilities.d.ts +65 -0
  42. package/dist/utils/ltiPlatformCapabilities.d.ts.map +1 -0
  43. package/dist/utils/ltiPlatformCapabilities.js +73 -0
  44. package/package.json +3 -3
  45. package/src/interfaces/index.ts +1 -0
  46. package/src/interfaces/ltiConfig.ts +25 -0
  47. package/src/interfaces/ltiDynamicRegistrationSession.ts +14 -0
  48. package/src/interfaces/ltiStorage.ts +32 -0
  49. package/src/ltiTool.ts +122 -1
  50. package/src/schemas/index.ts +17 -0
  51. package/src/schemas/lti13/dynamicRegistration/ltiDynamicRegistration.schema.ts +31 -0
  52. package/src/schemas/lti13/dynamicRegistration/ltiMessages.schema.ts +59 -0
  53. package/src/schemas/lti13/dynamicRegistration/openIDConfiguration.schema.ts +60 -0
  54. package/src/schemas/lti13/dynamicRegistration/registrationRequest.schema.ts +8 -0
  55. package/src/schemas/lti13/dynamicRegistration/registrationResponse.schema.ts +67 -0
  56. package/src/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.ts +55 -0
  57. package/src/services/dynamicRegistration.service.ts +406 -0
  58. package/src/services/dynamicRegistrationHandlers/moodle.ts +184 -0
  59. package/src/utils/ltiPlatformCapabilities.ts +86 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @lti-tool/core
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 3426ca4: Implement dynamic registration
8
+
9
+ ## 0.11.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 359a3fe: Update dependencies
14
+
3
15
  ## 0.11.0
4
16
 
5
17
  ### Minor Changes
@@ -1,6 +1,7 @@
1
1
  export type { LTIClient } from './ltiClient.js';
2
2
  export type { LTIConfig } from './ltiConfig.js';
3
3
  export type { LTIDeployment } from './ltiDeployment.js';
4
+ export type { LTIDynamicRegistrationSession } from './ltiDynamicRegistrationSession.js';
4
5
  export type { LTILaunchConfig } from './ltiLaunchConfig.js';
5
6
  export type { LTISession } from './ltiSession.js';
6
7
  export type { LTIStorage } from './ltiStorage.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACxF,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,5 +1,26 @@
1
1
  import type { Logger } from 'pino';
2
2
  import type { LTIStorage } from './ltiStorage.js';
3
+ /** Dynamic registration configuration for LTI 1.3 tool registration */
4
+ export interface DynamicRegistrationConfig {
5
+ /** Base URL of the LTI tool (e.g., 'https://my-tool.com') */
6
+ url: string;
7
+ /** Display name shown to users in the LMS (e.g., 'My Learning Tool') */
8
+ name: string;
9
+ /** Optional description of the tool's functionality */
10
+ description?: string;
11
+ /** Optional URL to tool logo image for LMS display */
12
+ logo?: string;
13
+ /** Additional redirect URIs beyond the default /lti/launch endpoint */
14
+ redirectUris?: string[];
15
+ /** Optional custom deep linking content selection endpoint (defaults to {url}/lti/deep-linking) */
16
+ deepLinkingUri?: string;
17
+ /** Optional custom login endpoint (defaults to {url}/lti/login) */
18
+ loginUri?: string;
19
+ /** Optional custom launch endpoint (defaults to {url}/lti/launch) */
20
+ launchUri?: string;
21
+ /** Optional custom JWKS endpoint (defaults to {url}/lti/jwks) */
22
+ jwksUri?: string;
23
+ }
3
24
  /**
4
25
  * Configuration object for initializing an LTI Tool instance.
5
26
  * Contains cryptographic keys, secrets, and storage adapter.
@@ -22,5 +43,7 @@ export interface LTIConfig {
22
43
  /** Nonce expiration time in seconds (defaults to 600 = 10 minutes) */
23
44
  nonceExpirationSeconds?: number;
24
45
  };
46
+ /** Dynamic registration configuration for LTI 1.3 tool registration */
47
+ dynamicRegistration?: DynamicRegistrationConfig;
25
48
  }
26
49
  //# sourceMappingURL=ltiConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ltiConfig.d.ts","sourceRoot":"","sources":["../../src/interfaces/ltiConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,6FAA6F;IAC7F,WAAW,EAAE,UAAU,CAAC;IAExB,gEAAgE;IAChE,OAAO,EAAE,aAAa,CAAC;IAEvB,qEAAqE;IACrE,OAAO,EAAE,UAAU,CAAC;IAEpB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,qCAAqC;IACrC,QAAQ,CAAC,EAAE;QACT,2DAA2D;QAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,0EAA0E;QAC1E,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC,sEAAsE;QACtE,sBAAsB,CAAC,EAAE,MAAM,CAAC;KACjC,CAAC;CACH"}
1
+ {"version":3,"file":"ltiConfig.d.ts","sourceRoot":"","sources":["../../src/interfaces/ltiConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,uEAAuE;AACvE,MAAM,WAAW,yBAAyB;IACxC,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,mGAAmG;IACnG,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,6FAA6F;IAC7F,WAAW,EAAE,UAAU,CAAC;IAExB,gEAAgE;IAChE,OAAO,EAAE,aAAa,CAAC;IAEvB,qEAAqE;IACrE,OAAO,EAAE,UAAU,CAAC;IAEpB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,qCAAqC;IACrC,QAAQ,CAAC,EAAE;QACT,2DAA2D;QAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,0EAA0E;QAC1E,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC,sEAAsE;QACtE,sBAAsB,CAAC,EAAE,MAAM,CAAC;KACjC,CAAC;IAEF,uEAAuE;IACvE,mBAAmB,CAAC,EAAE,yBAAyB,CAAC;CACjD"}
@@ -0,0 +1,14 @@
1
+ import type { OpenIDConfiguration } from '../schemas/lti13/dynamicRegistration/openIDConfiguration.schema';
2
+ /**
3
+ * Temporary session data stored during LTI 1.3 dynamic registration flow.
4
+ * Used to maintain state between the registration initiation and completion steps.
5
+ */
6
+ export interface LTIDynamicRegistrationSession {
7
+ /** Platform's OpenID Connect configuration retrieved during registration initiation */
8
+ openIdConfiguration: OpenIDConfiguration;
9
+ /** Registration token provided by the platform for this registration attempt */
10
+ registrationToken?: string;
11
+ /** Unix timestamp (milliseconds) when this session expires and should be cleaned up */
12
+ expiresAt: number;
13
+ }
14
+ //# sourceMappingURL=ltiDynamicRegistrationSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ltiDynamicRegistrationSession.d.ts","sourceRoot":"","sources":["../../src/interfaces/ltiDynamicRegistrationSession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iEAAiE,CAAC;AAE3G;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C,uFAAuF;IACvF,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uFAAuF;IACvF,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,6 @@
1
1
  import type { LTIClient } from './ltiClient.js';
2
2
  import type { LTIDeployment } from './ltiDeployment.js';
3
+ import type { LTIDynamicRegistrationSession } from './ltiDynamicRegistrationSession.js';
3
4
  import type { LTILaunchConfig } from './ltiLaunchConfig.js';
4
5
  import type { LTISession } from './ltiSession.js';
5
6
  /**
@@ -118,5 +119,26 @@ export interface LTIStorage {
118
119
  * @param launchConfig - Complete launch configuration with auth URLs and keys
119
120
  */
120
121
  saveLaunchConfig(launchConfig: LTILaunchConfig): Promise<void>;
122
+ /**
123
+ * Stores a temporary registration session during LTI 1.3 dynamic registration flow.
124
+ * Sessions have a TTL and are automatically cleaned up when expired.
125
+ *
126
+ * @param sessionId - Unique session identifier (typically a UUID)
127
+ * @param session - Registration session data including platform config and tokens
128
+ */
129
+ setRegistrationSession(sessionId: string, session: LTIDynamicRegistrationSession): Promise<void>;
130
+ /**
131
+ * Retrieves a registration session by its ID for validation during completion.
132
+ *
133
+ * @param sessionId - Unique session identifier
134
+ * @returns Registration session if found and not expired, undefined otherwise
135
+ */
136
+ getRegistrationSession(sessionId: string): Promise<LTIDynamicRegistrationSession | undefined>;
137
+ /**
138
+ * Removes a registration session from storage (cleanup after completion or expiration).
139
+ *
140
+ * @param sessionId - Unique session identifier to delete
141
+ */
142
+ deleteRegistrationSession(sessionId: string): Promise<void>;
121
143
  }
122
144
  //# sourceMappingURL=ltiStorage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ltiStorage.d.ts","sourceRoot":"","sources":["../../src/interfaces/ltiStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,UAAU;IAGzB;;;;OAIG;IACH,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IAEhE;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,aAAa,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1E;;;;;OAKG;IACH,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,aAAa,CAAC,CAAC,GACrD,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;OAIG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAI9C;;;;;OAKG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAE5D;;;;;;OAMG;IACH,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IAEtC;;;;;OAKG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExF;;;;;OAKG;IACH,gBAAgB,CACd,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;OAKG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAIxE;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAE/D;;;;;OAKG;IACH,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAIjD;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D;;;;;OAKG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAI/C;;;;;;;OAOG;IACH,eAAe,CACb,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC;IAExC;;;;OAIG;IACH,gBAAgB,CAAC,YAAY,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE"}
1
+ {"version":3,"file":"ltiStorage.d.ts","sourceRoot":"","sources":["../../src/interfaces/ltiStorage.ts"],"names":[],"mappings":"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"}
package/dist/ltiTool.d.ts CHANGED
@@ -2,11 +2,13 @@ import type { JWKS } from './interfaces/jwks.js';
2
2
  import type { LTIClient } from './interfaces/ltiClient.js';
3
3
  import type { LTIConfig } from './interfaces/ltiConfig.js';
4
4
  import type { LTIDeployment } from './interfaces/ltiDeployment.js';
5
+ import type { LTIDynamicRegistrationSession } from './interfaces/ltiDynamicRegistrationSession.js';
5
6
  import type { LTISession } from './interfaces/ltiSession.js';
6
- import { type LTI13JwtPayload } from './schemas/index.js';
7
+ import { type DynamicRegistrationForm, type LTI13JwtPayload, type RegistrationRequest } from './schemas/index.js';
7
8
  import { type CreateLineItem, type LineItem, type LineItems, type UpdateLineItem } from './schemas/lti13/ags/lineItem.schema.js';
8
9
  import { type Results } from './schemas/lti13/ags/result.schema.js';
9
10
  import { type ScoreSubmission } from './schemas/lti13/ags/scoreSubmission.schema.js';
11
+ import { type OpenIDConfiguration } from './schemas/lti13/dynamicRegistration/openIDConfiguration.schema.js';
10
12
  import { type Member } from './schemas/lti13/nrps/contextMembership.schema.js';
11
13
  /**
12
14
  * Main LTI 1.3 Tool implementation providing secure authentication, launch verification,
@@ -39,6 +41,7 @@ export declare class LTITool {
39
41
  private tokenService;
40
42
  private agsService;
41
43
  private nrpsService;
44
+ private dynamicRegistrationService?;
42
45
  /**
43
46
  * Creates a new LTI Tool instance.
44
47
  *
@@ -194,6 +197,43 @@ export declare class LTITool {
194
197
  * ```
195
198
  */
196
199
  getMembers(session: LTISession): Promise<Member[]>;
200
+ /**
201
+ * Fetches and validates the OpenID Connect configuration from an LTI platform during dynamic registration.
202
+ * Validates that the OIDC endpoint and issuer have matching hostnames for security.
203
+ *
204
+ * @param registrationRequest - Registration request containing openid_configuration URL and optional registration_token
205
+ * @returns Validated OpenID configuration with platform endpoints and supported features
206
+ * @throws {Error} When the configuration fetch fails, validation fails, or hostname mismatch detected
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * const config = await ltiTool.fetchPlatformConfiguration({
211
+ * openid_configuration: 'https://platform.edu/.well-known/openid_configuration',
212
+ * registration_token: 'optional-bearer-token'
213
+ * });
214
+ * console.log('Platform issuer:', config.issuer);
215
+ * ```
216
+ */
217
+ fetchPlatformConfiguration(registrationRequest: RegistrationRequest): Promise<OpenIDConfiguration>;
218
+ /**
219
+ * Initiates LTI 1.3 dynamic registration by fetching platform configuration and generating registration form.
220
+ * Creates a temporary session and returns vendor-specific HTML form for service selection.
221
+ *
222
+ * @param registrationRequest - Registration request containing openid_configuration URL and optional registration_token
223
+ * @param requestPath - Current request path used to build form action URLs
224
+ * @returns HTML form for service selection and registration completion
225
+ * @throws {Error} When dynamic registration service is not configured or platform configuration fails
226
+ */
227
+ initiateDynamicRegistration(registrationRequest: RegistrationRequest, requestPath: string): Promise<string>;
228
+ /**
229
+ * Completes LTI 1.3 dynamic registration by processing form submission and storing client configuration.
230
+ * Validates session, registers with platform, stores client/deployment data, and returns success page.
231
+ *
232
+ * @param dynamicRegistrationForm - Validated form data containing selected services and session token
233
+ * @returns HTML success page with registration details and close button
234
+ * @throws {Error} When dynamic registration service is not configured or registration process fails
235
+ */
236
+ completeDynamicRegistration(dynamicRegistrationForm: DynamicRegistrationForm): Promise<string>;
197
237
  /**
198
238
  * Retrieves all configured LTI client platforms.
199
239
  *
@@ -265,5 +305,28 @@ export declare class LTITool {
265
305
  * @param deploymentId - Deployment identifier to remove
266
306
  */
267
307
  deleteDeployment(clientId: string, deploymentId: string): Promise<void>;
308
+ /**
309
+ * Stores a temporary registration session during LTI 1.3 dynamic registration flow.
310
+ * Sessions automatically expire after the configured TTL period.
311
+ *
312
+ * @param sessionId - Unique session identifier (typically a UUID)
313
+ * @param session - Registration session data including platform config and tokens
314
+ */
315
+ setRegistrationSession(sessionId: string, session: LTIDynamicRegistrationSession): Promise<void>;
316
+ /**
317
+ * Retrieves a registration session by its ID for validation during completion.
318
+ * Returns undefined if the session is not found or has expired.
319
+ *
320
+ * @param sessionId - Unique session identifier
321
+ * @returns Registration session if found and not expired, undefined otherwise
322
+ */
323
+ getRegistrationSession(sessionId: string): Promise<LTIDynamicRegistrationSession | undefined>;
324
+ /**
325
+ * Removes a registration session from storage after completion or expiration.
326
+ * Used for cleanup to prevent session accumulation.
327
+ *
328
+ * @param sessionId - Unique session identifier to delete
329
+ */
330
+ deleteRegistrationSession(sessionId: string): Promise<void>;
268
331
  }
269
332
  //# sourceMappingURL=ltiTool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ltiTool.d.ts","sourceRoot":"","sources":["../src/ltiTool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ltiTool.d.ts","sourceRoot":"","sources":["../src/ltiTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,+CAA+C,CAAC;AACnG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EACL,KAAK,uBAAuB,EAE5B,KAAK,eAAe,EAEpB,KAAK,mBAAmB,EAGzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,SAAS,EAGd,KAAK,cAAc,EACpB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,mEAAmE,CAAC;AAC7G,OAAO,EACL,KAAK,MAAM,EAEZ,MAAM,kDAAkD,CAAC;AAQ1D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,OAAO;IAcN,OAAO,CAAC,MAAM;IAb1B,4DAA4D;IAC5D,OAAO,CAAC,SAAS,CAA4D;IAC7E,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,0BAA0B,CAAC,CAA6B;IAEhE;;;;OAIG;gBACiB,MAAM,EAAE,SAAS;IA6BrC;;;;;;;;;;;;;OAaG;IACG,WAAW,CAAC,MAAM,EAAE;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,GAAG,GAAG,MAAM,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,GAAG,OAAO,CAAC,MAAM,CAAC;IAgDnB;;;;;;;;;;;;;;OAcG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAuD5E;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAc9B;;;;;OAKG;IACG,aAAa,CAAC,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IAM1E;;;;;OAKG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAKpE;;;;;;OAMG;IACG,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7E;;;;;;;;;;;;OAYG;IACG,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAUtD;;;;;;OAMG;IACG,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IAU5D;;;;;;OAMG;IACG,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;IAUzD;;;;;;;;;;;;;;;;;;OAkBG;IACG,cAAc,CAClB,OAAO,EAAE,UAAU,EACnB,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,QAAQ,CAAC;IAapB;;;;;;;OAOG;IACG,cAAc,CAClB,OAAO,EAAE,UAAU,EACnB,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,QAAQ,CAAC;IAapB;;;;;OAKG;IACG,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAQxD;;;;;;;;;;;;;;OAcG;IACG,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAwBxD;;;;;;;;;;;;;;;;OAgBG;IACG,0BAA0B,CAC9B,mBAAmB,EAAE,mBAAmB,GACvC,OAAO,CAAC,mBAAmB,CAAC;IAS/B;;;;;;;;OAQG;IACG,2BAA2B,CAC/B,mBAAmB,EAAE,mBAAmB,EACxC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC;IAUlB;;;;;;;OAOG;IACG,2BAA2B,CAC/B,uBAAuB,EAAE,uBAAuB,GAC/C,OAAO,CAAC,MAAM,CAAC;IAYlB;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,CAAC;IAI9D;;;;;OAKG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,aAAa,CAAC,CAAC,GACrD,OAAO,CAAC,IAAI,CAAC;IAKhB;;;;;OAKG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAIrE;;;;;OAKG;IACG,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,aAAa,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/E;;;;OAIG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnD;;;;;OAKG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAIjE;;;;;;OAMG;IACG,aAAa,CACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAIrC;;;;;;OAMG;IACG,aAAa,CACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,GACpC,OAAO,CAAC,MAAM,CAAC;IAIlB;;;;;;OAMG;IACG,gBAAgB,CACpB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAIhB;;;;;OAKG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7E;;;;;;OAMG;IACG,sBAAsB,CAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,IAAI,CAAC;IAIhB;;;;;;OAMG;IACG,sBAAsB,CAC1B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,6BAA6B,GAAG,SAAS,CAAC;IAIrD;;;;;OAKG;IACG,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlE"}
package/dist/ltiTool.js CHANGED
@@ -5,6 +5,7 @@ import { LineItemSchema, LineItemsSchema, } from './schemas/lti13/ags/lineItem.s
5
5
  import { ResultsSchema } from './schemas/lti13/ags/result.schema.js';
6
6
  import { NRPSContextMembershipResponseSchema, } from './schemas/lti13/nrps/contextMembership.schema.js';
7
7
  import { AGSService } from './services/ags.service.js';
8
+ import { DynamicRegistrationService } from './services/dynamicRegistration.service.js';
8
9
  import { NRPSService } from './services/nrps.service.js';
9
10
  import { createSession } from './services/session.service.js';
10
11
  import { TokenService } from './services/token.service.js';
@@ -40,6 +41,7 @@ export class LTITool {
40
41
  tokenService;
41
42
  agsService;
42
43
  nrpsService;
44
+ dynamicRegistrationService;
43
45
  /**
44
46
  * Creates a new LTI Tool instance.
45
47
  *
@@ -58,6 +60,9 @@ export class LTITool {
58
60
  this.tokenService = new TokenService(this.config.keyPair, this.config.security?.keyId ?? 'main');
59
61
  this.agsService = new AGSService(this.tokenService, this.config.storage, this.logger);
60
62
  this.nrpsService = new NRPSService(this.tokenService, this.config.storage, this.logger);
63
+ if (this.config.dynamicRegistration) {
64
+ this.dynamicRegistrationService = new DynamicRegistrationService(this.config.storage, this.config.dynamicRegistration, this.logger);
65
+ }
61
66
  }
62
67
  /**
63
68
  * Handles LTI 1.3 login initiation by generating state/nonce and redirecting to platform auth.
@@ -345,7 +350,6 @@ export class LTITool {
345
350
  }
346
351
  const response = await this.nrpsService.getMembers(session);
347
352
  const data = await response.json();
348
- console.log(data);
349
353
  const validated = NRPSContextMembershipResponseSchema.parse(data);
350
354
  // Transform to clean camelCase format
351
355
  return validated.members.map((member) => ({
@@ -361,6 +365,58 @@ export class LTITool {
361
365
  roles: member.roles,
362
366
  }));
363
367
  }
368
+ /**
369
+ * Fetches and validates the OpenID Connect configuration from an LTI platform during dynamic registration.
370
+ * Validates that the OIDC endpoint and issuer have matching hostnames for security.
371
+ *
372
+ * @param registrationRequest - Registration request containing openid_configuration URL and optional registration_token
373
+ * @returns Validated OpenID configuration with platform endpoints and supported features
374
+ * @throws {Error} When the configuration fetch fails, validation fails, or hostname mismatch detected
375
+ *
376
+ * @example
377
+ * ```typescript
378
+ * const config = await ltiTool.fetchPlatformConfiguration({
379
+ * openid_configuration: 'https://platform.edu/.well-known/openid_configuration',
380
+ * registration_token: 'optional-bearer-token'
381
+ * });
382
+ * console.log('Platform issuer:', config.issuer);
383
+ * ```
384
+ */
385
+ async fetchPlatformConfiguration(registrationRequest) {
386
+ if (!this.dynamicRegistrationService) {
387
+ throw new Error('Dynamic registration service is not configured');
388
+ }
389
+ return await this.dynamicRegistrationService.fetchPlatformConfiguration(registrationRequest);
390
+ }
391
+ /**
392
+ * Initiates LTI 1.3 dynamic registration by fetching platform configuration and generating registration form.
393
+ * Creates a temporary session and returns vendor-specific HTML form for service selection.
394
+ *
395
+ * @param registrationRequest - Registration request containing openid_configuration URL and optional registration_token
396
+ * @param requestPath - Current request path used to build form action URLs
397
+ * @returns HTML form for service selection and registration completion
398
+ * @throws {Error} When dynamic registration service is not configured or platform configuration fails
399
+ */
400
+ async initiateDynamicRegistration(registrationRequest, requestPath) {
401
+ if (!this.dynamicRegistrationService) {
402
+ throw new Error('Dynamic registration service is not configured');
403
+ }
404
+ return await this.dynamicRegistrationService.initiateDynamicRegistration(registrationRequest, requestPath);
405
+ }
406
+ /**
407
+ * Completes LTI 1.3 dynamic registration by processing form submission and storing client configuration.
408
+ * Validates session, registers with platform, stores client/deployment data, and returns success page.
409
+ *
410
+ * @param dynamicRegistrationForm - Validated form data containing selected services and session token
411
+ * @returns HTML success page with registration details and close button
412
+ * @throws {Error} When dynamic registration service is not configured or registration process fails
413
+ */
414
+ async completeDynamicRegistration(dynamicRegistrationForm) {
415
+ if (!this.dynamicRegistrationService) {
416
+ throw new Error('Dynmaic registration service is not configured');
417
+ }
418
+ return await this.dynamicRegistrationService.completeDynamicRegistration(dynamicRegistrationForm);
419
+ }
364
420
  // Client management
365
421
  /**
366
422
  * Retrieves all configured LTI client platforms.
@@ -456,4 +512,34 @@ export class LTITool {
456
512
  async deleteDeployment(clientId, deploymentId) {
457
513
  return await this.config.storage.deleteDeployment(clientId, deploymentId);
458
514
  }
515
+ // Dynamic Registration Session Management
516
+ /**
517
+ * Stores a temporary registration session during LTI 1.3 dynamic registration flow.
518
+ * Sessions automatically expire after the configured TTL period.
519
+ *
520
+ * @param sessionId - Unique session identifier (typically a UUID)
521
+ * @param session - Registration session data including platform config and tokens
522
+ */
523
+ async setRegistrationSession(sessionId, session) {
524
+ return await this.config.storage.setRegistrationSession(sessionId, session);
525
+ }
526
+ /**
527
+ * Retrieves a registration session by its ID for validation during completion.
528
+ * Returns undefined if the session is not found or has expired.
529
+ *
530
+ * @param sessionId - Unique session identifier
531
+ * @returns Registration session if found and not expired, undefined otherwise
532
+ */
533
+ async getRegistrationSession(sessionId) {
534
+ return await this.config.storage.getRegistrationSession(sessionId);
535
+ }
536
+ /**
537
+ * Removes a registration session from storage after completion or expiration.
538
+ * Used for cleanup to prevent session accumulation.
539
+ *
540
+ * @param sessionId - Unique session identifier to delete
541
+ */
542
+ async deleteRegistrationSession(sessionId) {
543
+ return await this.config.storage.deleteRegistrationSession(sessionId);
544
+ }
459
545
  }
@@ -1,4 +1,9 @@
1
1
  export { SessionIdSchema } from './common.schema.js';
2
+ export { DynamicRegistrationFormSchema, type DynamicRegistrationForm, } from './lti13/dynamicRegistration/ltiDynamicRegistration.schema.js';
3
+ export { LTIMessagesArraySchema, type LTIMessage, } from './lti13/dynamicRegistration/ltiMessages.schema.js';
4
+ export { type OpenIDConfiguration } from './lti13/dynamicRegistration/openIDConfiguration.schema.js';
5
+ export { RegistrationRequestSchema, type RegistrationRequest, } from './lti13/dynamicRegistration/registrationRequest.schema.js';
6
+ export { RegistrationResponseSchema, type RegistrationResponse, } from './lti13/dynamicRegistration/registrationResponse.schema.js';
2
7
  export { LTI13JwtPayloadSchema, type LTI13JwtPayload, } from './lti13/lti13JwtPayload.schema.js';
3
8
  export { LTI13LaunchSchema, VerifyLaunchParamsSchema, } from './lti13/lti13Launch.schema.js';
4
9
  export { HandleLoginParamsSchema, LTI13LoginSchema } from './lti13/lti13Login.schema.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,GACrB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,6BAA6B,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,8DAA8D,CAAC;AACtE,OAAO,EACL,sBAAsB,EACtB,KAAK,UAAU,GAChB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,2DAA2D,CAAC;AACrG,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,GACzB,MAAM,2DAA2D,CAAC;AACnE,OAAO,EACL,0BAA0B,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,4DAA4D,CAAC;AACpE,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,GACrB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -1,4 +1,8 @@
1
1
  export { SessionIdSchema } from './common.schema.js';
2
+ export { DynamicRegistrationFormSchema, } from './lti13/dynamicRegistration/ltiDynamicRegistration.schema.js';
3
+ export { LTIMessagesArraySchema, } from './lti13/dynamicRegistration/ltiMessages.schema.js';
4
+ export { RegistrationRequestSchema, } from './lti13/dynamicRegistration/registrationRequest.schema.js';
5
+ export { RegistrationResponseSchema, } from './lti13/dynamicRegistration/registrationResponse.schema.js';
2
6
  export { LTI13JwtPayloadSchema, } from './lti13/lti13JwtPayload.schema.js';
3
7
  export { LTI13LaunchSchema, VerifyLaunchParamsSchema, } from './lti13/lti13Launch.schema.js';
4
8
  export { HandleLoginParamsSchema, LTI13LoginSchema } from './lti13/lti13Login.schema.js';
@@ -0,0 +1,34 @@
1
+ import * as z from 'zod';
2
+ /**
3
+ * Zod schema for validating LTI 1.3 dynamic registration form submissions.
4
+ * Represents the service selections and session data submitted by an administrator during tool registration.
5
+ *
6
+ * @property services - Optional array of LTI Advantage services the admin chooses to enable:
7
+ * - 'ags': Assignment and Grade Services for grade passback
8
+ * - 'nrps': Names and Role Provisioning Services for roster access
9
+ * - 'deep_linking': Deep Linking for content selection
10
+ * - 'tool_settings': Tool Settings service for configuration storage
11
+ * - 'basic_outcome': Basic Outcome service for simple grade reporting
12
+ * @property sessionToken - Security token to validate the registration session and prevent CSRF attacks
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const formData = {
17
+ * services: ['ags', 'nrps', 'deep_linking'],
18
+ * sessionToken: 'uuid-session-token'
19
+ * };
20
+ * const validated = DynamicRegistrationFormSchema.parse(formData);
21
+ * ```
22
+ */
23
+ export declare const DynamicRegistrationFormSchema: z.ZodObject<{
24
+ services: z.ZodOptional<z.ZodArray<z.ZodEnum<{
25
+ ags: "ags";
26
+ nrps: "nrps";
27
+ deep_linking: "deep_linking";
28
+ tool_settings: "tool_settings";
29
+ basic_outcome: "basic_outcome";
30
+ }>>>;
31
+ sessionToken: z.ZodString;
32
+ }, z.core.$strip>;
33
+ export type DynamicRegistrationForm = z.infer<typeof DynamicRegistrationFormSchema>;
34
+ //# sourceMappingURL=ltiDynamicRegistration.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ltiDynamicRegistration.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/dynamicRegistration/ltiDynamicRegistration.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,6BAA6B;;;;;;;;;iBAKxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import * as z from 'zod';
2
+ /**
3
+ * Zod schema for validating LTI 1.3 dynamic registration form submissions.
4
+ * Represents the service selections and session data submitted by an administrator during tool registration.
5
+ *
6
+ * @property services - Optional array of LTI Advantage services the admin chooses to enable:
7
+ * - 'ags': Assignment and Grade Services for grade passback
8
+ * - 'nrps': Names and Role Provisioning Services for roster access
9
+ * - 'deep_linking': Deep Linking for content selection
10
+ * - 'tool_settings': Tool Settings service for configuration storage
11
+ * - 'basic_outcome': Basic Outcome service for simple grade reporting
12
+ * @property sessionToken - Security token to validate the registration session and prevent CSRF attacks
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const formData = {
17
+ * services: ['ags', 'nrps', 'deep_linking'],
18
+ * sessionToken: 'uuid-session-token'
19
+ * };
20
+ * const validated = DynamicRegistrationFormSchema.parse(formData);
21
+ * ```
22
+ */
23
+ export const DynamicRegistrationFormSchema = z.object({
24
+ services: z
25
+ .array(z.enum(['ags', 'nrps', 'deep_linking', 'tool_settings', 'basic_outcome']))
26
+ .optional(),
27
+ sessionToken: z.string(),
28
+ });
@@ -0,0 +1,101 @@
1
+ import * as z from 'zod';
2
+ /**
3
+ * Zod schema for LTI 1.3 Resource Link Request message configuration.
4
+ * Represents the standard tool launch message type for accessing tool content.
5
+ * This is the most common LTI message type for regular tool launches.
6
+ */
7
+ declare const LTIResourceLinkMessageSchema: z.ZodObject<{
8
+ type: z.ZodLiteral<"LtiResourceLinkRequest">;
9
+ }, z.core.$strip>;
10
+ /**
11
+ * Zod schema for LTI 1.3 Deep Linking Request message configuration.
12
+ * Represents the message type used when the tool supports content selection/authoring.
13
+ * Allows instructors to select or create content that will be linked back to the LMS.
14
+ *
15
+ * @property type - Always 'LtiDeepLinkingRequest' for deep linking messages
16
+ * @property target_link_uri - Optional URL where deep linking requests should be sent
17
+ * @property label - Optional human-readable label for the deep linking option
18
+ * @property placements - Optional array of where the tool can be placed in the LMS UI
19
+ * @property supported_types - Optional array of content types the tool can create/select
20
+ * @property supported_media_types - Optional array of MIME types the tool supports
21
+ * @property roles - Optional array of LIS role URIs that can access deep linking
22
+ * @property custom_parameters - Optional custom parameters for deep linking configuration
23
+ */
24
+ declare const LTIDeepLinkingMessageSchema: z.ZodObject<{
25
+ type: z.ZodLiteral<"LtiDeepLinkingRequest">;
26
+ target_link_uri: z.ZodOptional<z.ZodURL>;
27
+ label: z.ZodOptional<z.ZodString>;
28
+ placements: z.ZodOptional<z.ZodArray<z.ZodEnum<{
29
+ ContentArea: "ContentArea";
30
+ RichTextEditor: "RichTextEditor";
31
+ CourseNavigation: "CourseNavigation";
32
+ }>>>;
33
+ supported_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
34
+ file: "file";
35
+ ltiResourceLink: "ltiResourceLink";
36
+ html: "html";
37
+ link: "link";
38
+ image: "image";
39
+ }>>>;
40
+ supported_media_types: z.ZodOptional<z.ZodArray<z.ZodString>>;
41
+ roles: z.ZodOptional<z.ZodArray<z.ZodString>>;
42
+ custom_parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
43
+ }, z.core.$strip>;
44
+ /**
45
+ * Discriminated union schema for all supported LTI 1.3 message types.
46
+ * Used during dynamic registration to declare which message types the tool supports.
47
+ * The platform uses this to determine what launch options to provide to users.
48
+ */
49
+ export declare const LTIMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
50
+ type: z.ZodLiteral<"LtiResourceLinkRequest">;
51
+ }, z.core.$strip>, z.ZodObject<{
52
+ type: z.ZodLiteral<"LtiDeepLinkingRequest">;
53
+ target_link_uri: z.ZodOptional<z.ZodURL>;
54
+ label: z.ZodOptional<z.ZodString>;
55
+ placements: z.ZodOptional<z.ZodArray<z.ZodEnum<{
56
+ ContentArea: "ContentArea";
57
+ RichTextEditor: "RichTextEditor";
58
+ CourseNavigation: "CourseNavigation";
59
+ }>>>;
60
+ supported_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
61
+ file: "file";
62
+ ltiResourceLink: "ltiResourceLink";
63
+ html: "html";
64
+ link: "link";
65
+ image: "image";
66
+ }>>>;
67
+ supported_media_types: z.ZodOptional<z.ZodArray<z.ZodString>>;
68
+ roles: z.ZodOptional<z.ZodArray<z.ZodString>>;
69
+ custom_parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
70
+ }, z.core.$strip>], "type">;
71
+ /**
72
+ * Schema for validating arrays of LTI message configurations.
73
+ * Used in tool registration payloads to declare multiple supported message types.
74
+ */
75
+ export declare const LTIMessagesArraySchema: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
76
+ type: z.ZodLiteral<"LtiResourceLinkRequest">;
77
+ }, z.core.$strip>, z.ZodObject<{
78
+ type: z.ZodLiteral<"LtiDeepLinkingRequest">;
79
+ target_link_uri: z.ZodOptional<z.ZodURL>;
80
+ label: z.ZodOptional<z.ZodString>;
81
+ placements: z.ZodOptional<z.ZodArray<z.ZodEnum<{
82
+ ContentArea: "ContentArea";
83
+ RichTextEditor: "RichTextEditor";
84
+ CourseNavigation: "CourseNavigation";
85
+ }>>>;
86
+ supported_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
87
+ file: "file";
88
+ ltiResourceLink: "ltiResourceLink";
89
+ html: "html";
90
+ link: "link";
91
+ image: "image";
92
+ }>>>;
93
+ supported_media_types: z.ZodOptional<z.ZodArray<z.ZodString>>;
94
+ roles: z.ZodOptional<z.ZodArray<z.ZodString>>;
95
+ custom_parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
96
+ }, z.core.$strip>], "type">>;
97
+ export type LTIMessage = z.infer<typeof LTIMessageSchema>;
98
+ export type LTIResourceLinkMessage = z.infer<typeof LTIResourceLinkMessageSchema>;
99
+ export type LTIDeepLinkingMessage = z.infer<typeof LTIDeepLinkingMessageSchema>;
100
+ export {};
101
+ //# sourceMappingURL=ltiMessages.schema.d.ts.map
@@ -0,0 +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;;;;;;;;;;;;;;;;;;;iBAa/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"}
@@ -0,0 +1,51 @@
1
+ import * as z from 'zod';
2
+ /**
3
+ * Zod schema for LTI 1.3 Resource Link Request message configuration.
4
+ * Represents the standard tool launch message type for accessing tool content.
5
+ * This is the most common LTI message type for regular tool launches.
6
+ */
7
+ const LTIResourceLinkMessageSchema = z.object({
8
+ type: z.literal('LtiResourceLinkRequest'),
9
+ });
10
+ /**
11
+ * Zod schema for LTI 1.3 Deep Linking Request message configuration.
12
+ * Represents the message type used when the tool supports content selection/authoring.
13
+ * Allows instructors to select or create content that will be linked back to the LMS.
14
+ *
15
+ * @property type - Always 'LtiDeepLinkingRequest' for deep linking messages
16
+ * @property target_link_uri - Optional URL where deep linking requests should be sent
17
+ * @property label - Optional human-readable label for the deep linking option
18
+ * @property placements - Optional array of where the tool can be placed in the LMS UI
19
+ * @property supported_types - Optional array of content types the tool can create/select
20
+ * @property supported_media_types - Optional array of MIME types the tool supports
21
+ * @property roles - Optional array of LIS role URIs that can access deep linking
22
+ * @property custom_parameters - Optional custom parameters for deep linking configuration
23
+ */
24
+ const LTIDeepLinkingMessageSchema = z.object({
25
+ type: z.literal('LtiDeepLinkingRequest'),
26
+ target_link_uri: z.url().optional(),
27
+ label: z.string().optional(),
28
+ placements: z
29
+ .array(z.enum(['ContentArea', 'RichTextEditor', 'CourseNavigation']))
30
+ .optional(),
31
+ supported_types: z
32
+ .array(z.enum(['ltiResourceLink', 'file', 'html', 'link', 'image']))
33
+ .optional(),
34
+ supported_media_types: z.array(z.string()).optional(), // e.g., ['image/*', 'video/*']
35
+ roles: z.array(z.string()).optional(), // LIS role URIs
36
+ custom_parameters: z.record(z.string(), z.string()).optional(),
37
+ });
38
+ /**
39
+ * Discriminated union schema for all supported LTI 1.3 message types.
40
+ * Used during dynamic registration to declare which message types the tool supports.
41
+ * The platform uses this to determine what launch options to provide to users.
42
+ */
43
+ export const LTIMessageSchema = z.discriminatedUnion('type', [
44
+ LTIResourceLinkMessageSchema,
45
+ LTIDeepLinkingMessageSchema,
46
+ ]);
47
+ /**
48
+ * Schema for validating arrays of LTI message configurations.
49
+ * Used in tool registration payloads to declare multiple supported message types.
50
+ */
51
+ export const LTIMessagesArraySchema = z.array(LTIMessageSchema);