ltijs
Version:
Easily turn your web application into a LTI 1.3 Learning Tool.
67 lines • 3.73 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LaunchContext = void 0;
const names_and_roles_service_1 = require("#services/names-and-roles/names-and-roles.service");
const grading_service_1 = require("#services/grading/grading.service");
const deep_linking_service_1 = require("#services/deep-linking/deep-linking.service");
const id_token_serializer_1 = require("#services/launch/id-token.serializer");
const REDIRECT_PLACEHOLDER_ORIGIN = 'http://ltijs-redirect-placeholder.invalid';
/**
* Everything a launch handler needs about the current launch -- passed as the first argument to
* `onResourceLink`/`onDeepLinking`/`onSubmissionReview`, and returned by `Provider.getLaunchContext(ltik)`
* to resume a launch outside the original request.
*/
class LaunchContext {
/** The full validated id_token record as stored, keyed by its database `id`. */
rawIdToken;
/** The id_token's claims, reshaped into ltijs's own (non-legacy) `IdToken` type. */
idToken;
/** The platform this launch came from. */
platform;
/** Opaque token identifying this launch -- pass it to `Provider.getLaunchContext` to resume the launch later. */
ltik;
// LTI Services
/** Names and Role Provisioning Service (NRPS) -- `getMembers()`. */
namesAndRoles;
/** Assignment and Grade Services (AGS) -- line items and score submission. */
grading;
/** Deep Linking service -- `createDeepLinkingMessage`/`createDeepLinkingForm`. */
deepLinking;
/** @deprecated Use {@link LaunchContext.idToken} instead. */
legacyIdToken;
// Derived, not stored -- always equal to rawIdToken.id, so a getter (rather than a separately
// assigned field) is the only representation that can't drift out of sync with it.
get contextId() {
return this.rawIdToken.id;
}
// eslint-disable-next-line @typescript-eslint/max-params
constructor(idToken, platform, ltik, accessTokenManager, requestHandler, logger) {
this.rawIdToken = idToken;
this.idToken = (0, id_token_serializer_1.buildIdToken)(idToken);
this.platform = platform;
this.ltik = ltik;
this.namesAndRoles = new names_and_roles_service_1.NamesAndRoles(this, accessTokenManager, requestHandler, logger);
this.grading = new grading_service_1.Grading(this, accessTokenManager, requestHandler, logger);
this.deepLinking = new deep_linking_service_1.DeepLinking(this, logger);
// eslint-disable-next-line @typescript-eslint/no-deprecated
this.legacyIdToken = (0, id_token_serializer_1.buildLegacyIdToken)(idToken);
}
/**
* Redirects to `path`, preserving its existing query parameters, merging in `options.query`, and always
* appending this launch's `ltik` (overriding any `ltik` already present in `path` or `options.query`),
* so a follow-up request through this same URL can still be resolved via `Provider.getLaunchContext`.
* `path` can be a plain path (`/grades`) or a full URL on another origin. Either way, only its query
* string is touched; everything else about it is preserved as given.
*/
redirect(response, path, options = {}) {
const url = new URL(path, REDIRECT_PLACEHOLDER_ORIGIN);
const isRelative = url.origin === REDIRECT_PLACEHOLDER_ORIGIN;
for (const [key, value] of Object.entries(options.query ?? {}))
url.searchParams.set(key, value);
url.searchParams.set('ltik', this.ltik);
response.redirect(isRelative ? `${url.pathname}${url.search}${url.hash}` : url.toString());
}
}
exports.LaunchContext = LaunchContext;
exports.default = LaunchContext;
//# sourceMappingURL=launch-context.service.js.map