@lti-tool/core 0.11.1 → 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.
- package/CHANGELOG.md +6 -0
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/interfaces/index.d.ts.map +1 -1
- package/dist/interfaces/ltiConfig.d.ts +23 -0
- package/dist/interfaces/ltiConfig.d.ts.map +1 -1
- package/dist/interfaces/ltiDynamicRegistrationSession.d.ts +14 -0
- package/dist/interfaces/ltiDynamicRegistrationSession.d.ts.map +1 -0
- package/dist/interfaces/ltiDynamicRegistrationSession.js +1 -0
- package/dist/interfaces/ltiStorage.d.ts +22 -0
- package/dist/interfaces/ltiStorage.d.ts.map +1 -1
- package/dist/ltiTool.d.ts +64 -1
- package/dist/ltiTool.d.ts.map +1 -1
- package/dist/ltiTool.js +87 -1
- package/dist/schemas/index.d.ts +5 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +4 -0
- package/dist/schemas/lti13/dynamicRegistration/ltiDynamicRegistration.schema.d.ts +34 -0
- package/dist/schemas/lti13/dynamicRegistration/ltiDynamicRegistration.schema.d.ts.map +1 -0
- package/dist/schemas/lti13/dynamicRegistration/ltiDynamicRegistration.schema.js +28 -0
- package/dist/schemas/lti13/dynamicRegistration/ltiMessages.schema.d.ts +101 -0
- package/dist/schemas/lti13/dynamicRegistration/ltiMessages.schema.d.ts.map +1 -0
- package/dist/schemas/lti13/dynamicRegistration/ltiMessages.schema.js +51 -0
- package/dist/schemas/lti13/dynamicRegistration/openIDConfiguration.schema.d.ts +59 -0
- package/dist/schemas/lti13/dynamicRegistration/openIDConfiguration.schema.d.ts.map +1 -0
- package/dist/schemas/lti13/dynamicRegistration/openIDConfiguration.schema.js +53 -0
- package/dist/schemas/lti13/dynamicRegistration/registrationRequest.schema.d.ts +7 -0
- package/dist/schemas/lti13/dynamicRegistration/registrationRequest.schema.d.ts.map +1 -0
- package/dist/schemas/lti13/dynamicRegistration/registrationRequest.schema.js +5 -0
- package/dist/schemas/lti13/dynamicRegistration/registrationResponse.schema.d.ts +73 -0
- package/dist/schemas/lti13/dynamicRegistration/registrationResponse.schema.d.ts.map +1 -0
- package/dist/schemas/lti13/dynamicRegistration/registrationResponse.schema.js +61 -0
- package/dist/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.d.ts +103 -0
- package/dist/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.d.ts.map +1 -0
- package/dist/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.js +49 -0
- package/dist/services/dynamicRegistration.service.d.ts +121 -0
- package/dist/services/dynamicRegistration.service.d.ts.map +1 -0
- package/dist/services/dynamicRegistration.service.js +312 -0
- package/dist/services/dynamicRegistrationHandlers/moodle.d.ts +48 -0
- package/dist/services/dynamicRegistrationHandlers/moodle.d.ts.map +1 -0
- package/dist/services/dynamicRegistrationHandlers/moodle.js +152 -0
- package/dist/utils/ltiPlatformCapabilities.d.ts +65 -0
- package/dist/utils/ltiPlatformCapabilities.d.ts.map +1 -0
- package/dist/utils/ltiPlatformCapabilities.js +73 -0
- package/package.json +1 -1
- package/src/interfaces/index.ts +1 -0
- package/src/interfaces/ltiConfig.ts +25 -0
- package/src/interfaces/ltiDynamicRegistrationSession.ts +14 -0
- package/src/interfaces/ltiStorage.ts +32 -0
- package/src/ltiTool.ts +122 -1
- package/src/schemas/index.ts +17 -0
- package/src/schemas/lti13/dynamicRegistration/ltiDynamicRegistration.schema.ts +31 -0
- package/src/schemas/lti13/dynamicRegistration/ltiMessages.schema.ts +59 -0
- package/src/schemas/lti13/dynamicRegistration/openIDConfiguration.schema.ts +60 -0
- package/src/schemas/lti13/dynamicRegistration/registrationRequest.schema.ts +8 -0
- package/src/schemas/lti13/dynamicRegistration/registrationResponse.schema.ts +67 -0
- package/src/schemas/lti13/dynamicRegistration/toolRegistrationPayload.schema.ts +55 -0
- package/src/services/dynamicRegistration.service.ts +406 -0
- package/src/services/dynamicRegistrationHandlers/moodle.ts +184 -0
- package/src/utils/ltiPlatformCapabilities.ts +86 -0
package/CHANGELOG.md
CHANGED
|
@@ -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;
|
|
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;
|
|
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
|
package/dist/ltiTool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,
|
|
1
|
+
{"version":3,"file":"ltiTool.d.ts","sourceRoot":"","sources":["../src/ltiTool.ts"],"names":[],"mappings":"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"}
|
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
|
}
|
package/dist/schemas/index.d.ts
CHANGED
|
@@ -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"}
|
package/dist/schemas/index.js
CHANGED
|
@@ -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);
|