{"_id":"@codewritz/ims-lti","_rev":"1-4f6d973e43a80f5cf31f6b64cb69fac8","name":"@codewritz/ims-lti","dist-tags":{"latest":"3.0.4"},"versions":{"3.0.3":{"name":"@codewritz/ims-lti","version":"3.0.3","description":"Module for building an LTI Tool Provider and accept LTI launch requests","author":{"name":"Yuri","email":"yuri@codewritz.com"},"contributors":[{"name":"Owen Smith","email":"owen@omsmith.ca"},{"name":"David Kosub","email":"dave@davidkosub.com"},{"name":"Yuri","email":"yuri@codewritz.com"}],"license":"MIT","keywords":["ims","lti","provider"],"repository":{"type":"git","url":"git+https://github.com/codewritz-repo/codewritz-ims-lti.git"},"bugs":{"url":"http://github.com/omsmith/ims-lti/issues"},"main":"./lib/ims-lti","scripts":{"prepublish":"make build"},"dependencies":{"xml2js":"~0.4.0","xmlbuilder":"~2.4.0","node-uuid":"~1.4.0"},"devDependencies":{"coffee-coverage":"^0.4.4","coffee-script":"^1.8.0","coveralls":"^2.11.2","mocha":"^2.1.0","mocha-lcov-reporter":"0.0.1","mocha-multi":"^0.6.0","redis":"^0.12.1","should":"^4.6.1"},"_id":"@codewritz/ims-lti@3.0.3","gitHead":"04aa24b290ff8f3d5d81a64ba6da2120f0d2a8fe","homepage":"https://github.com/codewritz-repo/codewritz-ims-lti#readme","_nodeVersion":"18.19.0","_npmVersion":"10.2.1","dist":{"integrity":"sha512-SWV0/mzZwMQUxOev3Zn+aO0Ix6at5509/Zojym205RyqRrDmkG2xAhF40G35/Fx6XXu2QFH7QvoOIc1Uk4zkQw==","shasum":"d1d9f95043391648d691481c525999f4766058ce","tarball":"https://registry.npmjs.org/@codewritz/ims-lti/-/ims-lti-3.0.3.tgz","fileCount":16,"unpackedSize":43945,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC/GsjCrnWKLYEhd1mzo7tkTbehvRIZm7EzVRoCpHrSfwIgK/wznIToBRuzCT6sMOojlutfLFMAS+6PpKtn3Y6Tol8="}]},"_npmUser":{"name":"codewritz","email":"dev@codewritz.com"},"directories":{},"maintainers":[{"name":"codewritz","email":"dev@codewritz.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ims-lti_3.0.3_1708343620934_0.8340435480087893"},"_hasShrinkwrap":false},"3.0.4":{"name":"@codewritz/ims-lti","version":"3.0.4","description":"Module for building an LTI Tool Provider and accept LTI launch requests","author":{"name":"Yuri","email":"yuri@codewritz.com"},"contributors":[{"name":"Owen Smith","email":"owen@omsmith.ca"},{"name":"David Kosub","email":"dave@davidkosub.com"},{"name":"Yuri","email":"yuri@codewritz.com"}],"license":"MIT","keywords":["ims","lti","provider"],"repository":{"type":"git","url":"git+https://github.com/codewritz-repo/codewritz-ims-lti.git"},"bugs":{"url":"http://github.com/omsmith/ims-lti/issues"},"main":"./lib/ims-lti","scripts":{"prepublish":"make build"},"dependencies":{"xml2js":"~0.4.0","xmlbuilder":"~2.4.0","node-uuid":"~1.4.0"},"devDependencies":{"coffee-coverage":"^0.4.4","coffee-script":"^1.8.0","coveralls":"^2.11.2","mocha":"^2.1.0","mocha-lcov-reporter":"0.0.1","mocha-multi":"^0.6.0","redis":"^0.12.1","should":"^4.6.1"},"_id":"@codewritz/ims-lti@3.0.4","gitHead":"0f388dfebd7a76e7f5977e8db1076bb33e1164af","homepage":"https://github.com/codewritz-repo/codewritz-ims-lti#readme","_nodeVersion":"18.19.0","_npmVersion":"10.2.1","dist":{"integrity":"sha512-dYfjGkryc1fvOpgIDNOvEb2L0vd7cqrFMp4zVZMh24I/U3P8CtQloXgK0t09H9pTudb74SKNc+hzXDc6/Z7JjA==","shasum":"67f8b402a9651eb7e4e9fe445fbaf24a5b303a70","tarball":"https://registry.npmjs.org/@codewritz/ims-lti/-/ims-lti-3.0.4.tgz","fileCount":16,"unpackedSize":43984,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHeD8XFKDWBUqmHpCklM8MX2yHCkLbBc0V/y4CuTkC4ZAiBX71QMN3zEE2FElPhR/kr9UPYI5H9hLNxwkSrBC0I9og=="}]},"_npmUser":{"name":"codewritz","email":"dev@codewritz.com"},"directories":{},"maintainers":[{"name":"codewritz","email":"dev@codewritz.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ims-lti_3.0.4_1708343924287_0.5305376108108477"},"_hasShrinkwrap":false}},"time":{"created":"2024-02-19T11:53:40.829Z","3.0.3":"2024-02-19T11:53:41.088Z","modified":"2024-02-19T11:58:44.885Z","3.0.4":"2024-02-19T11:58:44.483Z"},"maintainers":[{"name":"codewritz","email":"dev@codewritz.com"}],"description":"Module for building an LTI Tool Provider and accept LTI launch requests","homepage":"https://github.com/codewritz-repo/codewritz-ims-lti#readme","keywords":["ims","lti","provider"],"repository":{"type":"git","url":"git+https://github.com/codewritz-repo/codewritz-ims-lti.git"},"contributors":[{"name":"Owen Smith","email":"owen@omsmith.ca"},{"name":"David Kosub","email":"dave@davidkosub.com"},{"name":"Yuri","email":"yuri@codewritz.com"}],"author":{"name":"Yuri","email":"yuri@codewritz.com"},"bugs":{"url":"http://github.com/omsmith/ims-lti/issues"},"license":"MIT","readme":"# ims-lti\n\n[![Build Status](https://travis-ci.org/omsmith/ims-lti.svg?branch=master)](https://travis-ci.org/omsmith/ims-lti) [![Coverage Status](https://coveralls.io/repos/omsmith/ims-lti/badge.png)](https://coveralls.io/r/omsmith/ims-lti)\n\nThis is a nodejs library used to help create Tool Providers for the\n[IMS LTI standard](http://www.imsglobal.org/lti/index.html). Tool Consumer implmentation is left as an excersise to the reader :P\n\n## Install\n```\nnpm install ims-lti --save\n```\n\nTo require the library into your project\n```coffeescript\nrequire 'ims-lti'\n```\n\n## Supported LTI Versions\n\n* 1.0 - [Implementation Guide](http://www.imsglobal.org/lti/blti/bltiv1p0/ltiBLTIimgv1p0.html)\n* 1.1 - [Implementation Guide](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html)\n* 1.1.1 - [Implementation Guide](http://www.imsglobal.org/LTI/v1p1p1/ltiIMGv1p1p1.html)\n\n## Usage\n\nThe LTI standard won't be covered here, but it would be good to familiarize yourself with the specs. [LTI documentation](http://www.imsglobal.org/lti/index.html)\n\nThis library doesn't help you manage or distribute the consumer keys and secrets. The POST\nparameters will contain the `oauth_consumer_key` and your application should use that to look up the consumer secret from your own datastore.\n\nThis library offers a few interfaces to use for managing the OAuth nonces to make sure the same nonce\nisn't used twice with the same timestamp. [Read the LTI documentation on OAuth](http://www.imsglobal.org/LTI/v1p1pd/ltiIMGv1p1pd.html#_Toc309649687). They will be covered below.\n\n### Setting up a Tool Provider (TP)\nAs a TP your app will receive a POST request with [LTI launch data](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684) that will be signed with OAuth using a key/secret that both the TP and Tool Consumer (TC) share. This is all covered in the [LTI security model](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649685)\n\nOnce you find the `oauth_consumer_secret` based on the `oauth_consumer_key` in the POST request, you can initialize a `Provider` object with them and a few other optional parameters:\n\n```coffeescript\nlti = require 'ims-lti'\n\nprovider = new lti.Provider consumer_key, consumer_secret, [nonce_store=MemoryStore], [signature_method=HMAC_SHA1]\n```\n\nOnce the provider has been initialized, a reqest object can be validated against it. During validation, OAuth signatures are checked against the passed consumer_secret and signautre_method ( HMAC_SHA1 assumed ). isValid returns true if the request is an lti request and is properly signed.\n\n```coffeescript\nprovider.valid_request req, (err, isValid) ->\n  # isValid = Boolean | always false if err\n  # err = Error object with method descibing error if err, null if no error\n```\n\nAfter validating the reqest, the provider object both stores the requests parameters (excluding oauth parameters) and provides convinience accessors to common onces including `provider.student`, `provider.ta`, `provider.username`, and more. All request data can be accessed through `provider.body` in an effort to namespace the values.\n\nCurrently there is not an emplementation for posting back to the Tool Consumer, although there is a boolean accessor `provider.outcome_service` that will return true if the TC will accept a POSTback.\n\n### Nonce Stores\n\n`ims-lti` does not standardize the way in which the OAuth nonce/timestamp is to be stored. Since it is a crutial part of OAuth security, this library implements an Interface to allow the user to implement their own nonce-stores.\n\n#### Nonce Interface\nAll custom Nonce stores should extend the NonceStore class and implment `isNew` and `setUsed`\n```coffeescript\nclass NonceStore\n  isNew:   (nonce,timestamp,callback)=>\n    # Sets any new nonce to used\n  setUsed: (nonce,timestamp,callback)=>\n```\n\nTwo nonce stores have been implemented for convinience.\n\n#### MemoryNonceStore\nThe default nonce store (if none is specified) is the Memory Nonce Store. This store simply keeps an array of nocne/timestamp keys. Timestamps must be valid within a 5 minute grace period.\n\n#### RedisNonceStore\nA superior nonce store is the RedisNonceStore. This store requires a secondary input into the constructor, a redis-client. The redis client is used to store the nonce keys and set them to expire within a set amount of time (default 5 minutes). A RedisNonceStore is initialized like:\n\n```coffeescript\nRedisNonceStore = require '../lib/redis-nonce-store'\nclient          = require('redis').createClient()\nstore           = new RedisNonceStore('consumer_key', client)\n\nprovider = new lti.Provider consumer_key, consumer_secret, store\n```\n\n### Outcomes Extension\n\nThe outcomes feature is part of the LTI 1.1 specification and is new to ims-lti 1.0. All of the behind-the-scenes work necessary to get the ball rolling with it is already implemented for you, all you need to do is submit grades.\n\n```coffeescript\nprovider = new lti.Provider consumer_key, consumer_secret\n\nprovider.valid_request req, (err, is_valid) ->\n  # Check if the request is valid and if the outcomes service exists.\n  if (!is_valid || !provider.outcome_service) return false\n\n  # Check if the outcome service supports the result data extension using the\n  # text format. Available formats include text and url.\n  console.log provider.outcome_service.supports_result_data('text')\n\n  # Replace accepts a value between 0 and 1.\n  provider.outcome_service.send_replace_result .5, (err, result) ->\n    console.log result # True or false\n\n  provider.outcome_service.send_read_result (err, result) ->\n    console.log result # Value of the result already submitted from this embed\n\n  provider.outcome_service.send_delete_result (err, result) ->\n    console.log result # True or false\n\n  provider.outcome_service.send_replace_result_with_text .5, 'Hello, world!', (err, result) ->\n    console.log result # True or false\n\n  provider.outcome_service.send_replace_result_with_url .5, 'https://google.com', (err, result) ->\n    console.log result # True or false\n```\n\n### Content Extension\n\nThe content extension is an extension supported by most LMS platforms. It provides LTI providers a way to send content back to the LMS in the form of urls, images, files, oembeds, iframes, and even lti launch urls.\n\n```coffeescript\nprovider = new lti.Provider consumer_key, consumer_secret\n\nprovider.valid_request req, (err, is_valid) ->\n  #check if the request is valid and if the content extension is loaded.\n  if (!is_valid || !provider.ext_content) return false\n\n  provider.ext_content.has_return_type 'file' # Does the consumer support files\n  provider.ext_content.has_file_extension 'jpg' # Does the consumer support jpg\n\n  # All send requests take a response object as the first parameter. How the\n  # response object is manipulated can be overrided by replacing\n  # lti.Extensions.Content.redirector with your own function that accepts two\n  # parameters, the response object and the url to redirect to.\n  provider.ext_content.send_file res, file_url, text, content_mime_type\n\n  provider.ext_content.send_iframe res, iframe_url, title_attribute, width, height\n\n  provider.ext_content.send_image_url res, image_url, text, width, height\n\n  provider.ext_content.send_lti_launch_url res, launch_url, title_attribute, text\n\n  provider.ext_content.send_oembed res, oembed_url, endpoint\n\n  provider.ext_content.send_url res, hyperlink_url, text, title_attribute, target_attribute\n```\n\n## Running Tests\nTo run the test suite first installing the dependencies:\n```\nnpm install\nmake test\n```\n","readmeFilename":"README.md"}