// Save as add-lti-tool.mjs. Run on your server, never in the browser. function requiredEnv(name) { const value = process.env[name]; if (!value) throw new Error(`Set ${name} before running this example.`); return value; } const authorization = "Basic " + Buffer.from( requiredEnv("SCORMBOX_API_KEY") + ":" + requiredEnv("SCORMBOX_API_SECRET") ).toString("base64"); async function requestJson(path, body) { const response = await fetch("https://scormbox.com/api/v1" + path, { method: "POST", headers: { Authorization: authorization, "Content-Type": "application/json" }, body: JSON.stringify(body) }); const result = await response.json(); if (!response.ok) throw new Error(result.error || `HTTP ${response.status}`); return result; } const version = process.env.LTI_VERSION || "1.3"; if (!["1.1", "1.3"].includes(version)) throw new Error("Use LTI_VERSION 1.1 or 1.3."); const connection_input = { name: process.env.LTI_TOOL_NAME || "My LTI tool", version, launch_url: requiredEnv("LTI_LAUNCH_URL") }; if (version === "1.1") { connection_input.consumer_key = requiredEnv("LTI_CONSUMER_KEY"); connection_input.shared_secret = requiredEnv("LTI_SHARED_SECRET"); } else { connection_input.login_url = requiredEnv("LTI_LOGIN_URL"); connection_input.redirect_uris = [requiredEnv("LTI_REDIRECT_URI")]; connection_input.jwks_url = requiredEnv("LTI_JWKS_URL"); } const connection = await requestJson("/lti/connections", connection_input); const course = await requestJson("/courses", { format: "lti", connection_id: connection.id, title: connection_input.name, shareable: false }); console.log(JSON.stringify({ connection_id: connection.id, course_id: course.course_id, management_url: course.management_url, ...(version === "1.3" ? { platform_settings: { issuer: connection.issuer, client_id: connection.client_id, deployment_id: connection.deployment_id, auth_url: connection.auth_url, token_url: connection.token_url, jwks_url: connection.jwks_url } } : {}) }, null, 2));