{"id":16430,"library":"ltijs-sequelize","title":"Ltijs Sequelize Database Plugin","description":"Ltijs Sequelize Database Plugin is an official plugin for the LTI Advantage Complete Certified `ltijs` library, enabling it to persist LTI platform and deployment data using databases supported by Sequelize. It provides a robust, production-ready solution for managing LTI data with relational databases like MySQL, PostgreSQL, and MariaDB. The current stable version is 2.4.4, with releases often coinciding with new feature additions or compatibility updates for the core `ltijs` library, as seen with versions 2.4.0 and 2.3.0 introducing support for new `ltijs` features. This tight integration ensures seamless operation and access to advanced LTI features like Dynamic Registration Service and `authorizationServer` platform fields. Its primary differentiation is its certified compatibility and direct integration with `ltijs`, offering a tested and reliable database solution for LTI service providers.","status":"active","version":"2.4.4","language":"javascript","source_language":"en","source_url":"https://github.com/Cvmcosta/ltijs-sequelize","tags":["javascript","ltijs","lti","postgresql","postgres","mysql","sequelize","provider","ims"],"install":[{"cmd":"npm install ltijs-sequelize","lang":"bash","label":"npm"},{"cmd":"yarn add ltijs-sequelize","lang":"bash","label":"yarn"},{"cmd":"pnpm add ltijs-sequelize","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core LTI library that this package extends for database persistence. Specific `ltijs-sequelize` versions are compatible with specific `ltijs` versions (e.g., `^2.4.2` with `^5.7.0`).","package":"ltijs","optional":false},{"reason":"Underlying ORM used for database interaction. Users must install a compatible Sequelize version.","package":"sequelize","optional":false},{"reason":"Required if using 'mysql' or 'mariadb' dialect with Sequelize. Needs to be installed separately by the user.","package":"mysql2","optional":true},{"reason":"Required if using 'postgres' dialect with Sequelize. Needs to be installed separately by the user, often alongside `pg-hstore`.","package":"pg","optional":true},{"reason":"Required if using 'mssql' dialect with Sequelize. Needs to be installed separately by the user.","package":"tedious","optional":true},{"reason":"Required if using 'sqlite' dialect with Sequelize. Needs to be installed separately by the user.","package":"sqlite3","optional":true}],"imports":[{"note":"The `ltijs-sequelize` package exports the `Database` class as its default export. While CommonJS `require` can often handle default exports, explicit `module.exports = Database` or `exports.default = Database` patterns might be expected by some `require` implementations.","wrong":"import { Database } from 'ltijs-sequelize'","symbol":"Database","correct":"import Database from 'ltijs-sequelize'"},{"note":"This plugin works with an instance of `ltijs.Provider`. While the example uses `const lti = require('ltijs').Provider` for CommonJS, modern usage often prefers named ESM imports for `Provider` from `ltijs`.","wrong":"import Provider from 'ltijs'","symbol":"Provider (from ltijs)","correct":"import { Provider } from 'ltijs'"},{"note":"For TypeScript projects, while `ltijs-sequelize` itself exports a class, its constructor options are directly derived from Sequelize's constructor options. Importing `Options` as `SequelizeOptions` from `sequelize` helps type-check the options object passed to the `ltijs-sequelize` Database constructor.","symbol":"SequelizeOptions (type)","correct":"import type { Options as SequelizeOptions } from 'sequelize';"}],"quickstart":{"code":"const path = require('path')\n\n// Require Provider \nconst lti = require('ltijs').Provider\nconst Database = require('ltijs-sequelize')\n\n// Setup ltijs-sequelize using the same arguments as Sequelize's generic contructor\nconst db = new Database('database', 'user', 'password', \n  { \n    host: 'localhost',\n    dialect: 'mysql', // Or 'postgres', 'mariadb', 'mssql', 'sqlite'\n    logging: false,\n    // Other Sequelize options like pool, define, etc.\n    // Example: dialectOptions for SSL for PostgreSQL on Heroku\n    // dialectOptions: {\n    //   ssl: {\n    //     require: true,\n    //     rejectUnauthorized: false\n    //   }\n    // }\n  })\n\n// Setup provider, passing the db object to the plugin field\nlti.setup(process.env.LTIJS_KEY ?? 'LTIKEY_YOUR_SECRET', // Key used to sign cookies and tokens. USE A STRONG RANDOM KEY!\n  { \n    plugin: db // Passing db object to plugin field\n  },\n  { // Optional Ltijs configuration options\n    appRoute: '/', \n    loginRoute: '/login', \n    cookies: {\n      secure: process.env.NODE_ENV === 'production', // Set to true in production\n      sameSite: 'none' // Required for cross-site LTI launches\n    },\n    // Other Ltijs options like devMode, staticPath, etc.\n    // example: staticPath: path.join(__dirname, './public')\n  })\n\n// Example of how to initialize and connect\nasync function startLti() {\n  try {\n    await db.deploy(); // Deploys database schema, creates tables if they don't exist\n    await lti.deploy(); // Deploys Ltijs, setting up routes and middleware\n    console.log('LTI and Database plugin deployed successfully.');\n  } catch (err) {\n    console.error('Failed to deploy LTI or database plugin:', err);\n    process.exit(1);\n  }\n}\n\nstartLti();","lang":"javascript","description":"This example demonstrates how to initialize the `ltijs-sequelize` database plugin with specific Sequelize options (e.g., dialect, host) and integrate it with the `ltijs.Provider` instance, followed by deploying both the database schema and the LTI provider."},"warnings":[{"fix":"Always consult the `ltijs-sequelize` compatibility table in the README to ensure your `ltijs-sequelize` version matches your `ltijs` version (e.g., `ltijs-sequelize@^2.4.2` requires `ltijs@^5.7.0`). Update both packages concurrently if necessary.","message":"Compatibility between `ltijs-sequelize` and `ltijs` is strict and tied to specific major/minor versions. Using an incompatible `ltijs-sequelize` version with a new `ltijs` major or minor release can lead to runtime errors or unexpected behavior due to schema or API changes.","severity":"breaking","affected_versions":"All versions"},{"fix":"Ensure your `Database` constructor call is structured like `new Database('db', 'user', 'pass', { host: 'localhost', dialect: 'mysql', ...otherOptions })`.","message":"When initializing the `Database` plugin, the `options` object passed to the constructor *must* explicitly include `host` and `dialect` fields, which are fundamental for Sequelize to connect to your chosen database.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Review `ltijs-sequelize` changelogs for schema updates before deploying new versions. Consider disabling automatic migrations or managing them manually in critical production systems if fine-grained control over schema changes is required (if the library offers a way to do so).","message":"As of `ltijs-sequelize` v2.4.0, automatic database migrations are supported. While this feature enhances flexibility, it means schema changes might be applied automatically, which could be an unexpected behavior for production environments without proper review.","severity":"breaking","affected_versions":">=2.4.0"},{"fix":"Set `cookies: { secure: true, sameSite: 'none' }` in your `lti.setup` configuration for production deployments. Use environment variables (e.g., `process.env.NODE_ENV === 'production'`) to conditionally enable `secure: true`.","message":"The `ltijs.setup` `cookies.secure` option should be set to `true` in production to prevent cookies from being sent over insecure connections, which is a security vulnerability for LTI messages. `sameSite: 'none'` is also critical for cross-site LTI launches.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Install the appropriate database driver package (e.g., `npm install mysql2` for `mysql` or `mariadb` dialects, `npm install pg pg-hstore` for `postgres` dialect, `npm install tedious` for `mssql` dialect) alongside `sequelize` and `ltijs-sequelize`.","message":"This plugin requires specific database drivers (e.g., `mysql2`, `pg`, `tedious`) to be installed separately based on the `dialect` chosen in the Sequelize options. Failure to install the correct driver will result in connection errors.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Verify your database server is running and configured to accept connections from the host where your Node.js application is running. Check firewall rules, database server status, and the `host` and `port` settings in your `Database` constructor options.","cause":"The database server is not running or is not accessible from the application's host and port specified in the Sequelize options.","error":"SequelizeConnectionError: connect ECONNREFUSED 127.0.0.1:3306"},{"fix":"Double-check the `dialect` spelling. Ensure you have installed the correct Sequelize driver package (e.g., `npm install mysql2` for MySQL, `npm install pg pg-hstore` for PostgreSQL) in addition to `sequelize` and `ltijs-sequelize`.","cause":"The specified `dialect` in the `Database` options is either misspelled, unsupported by the installed Sequelize version, or the necessary database driver package (e.g., `mysql2` for `mysql`) has not been installed.","error":"Error: The dialect mysql is not supported. Please use one of the following: mariadb, postgres, mssql, sqlite"},{"fix":"Ensure you import or require the `Provider` export correctly from `ltijs`, typically as `import { Provider as LtiProvider } from 'ltijs'` or `const lti = require('ltijs').Provider`.","cause":"The `lti` object was incorrectly imported or instantiated from the `ltijs` package. `setup` is a method of the `Provider` instance, not the top-level `ltijs` module itself.","error":"TypeError: Cannot read properties of undefined (reading 'setup')"},{"fix":"Ensure that an instantiated `ltijs-sequelize` `Database` object is correctly passed to the `plugin` field in `lti.setup` configuration: `lti.setup('LTIKEY', { plugin: db }, { ...options })`.","cause":"The `ltijs.setup` method was called without providing a `plugin` object in its configuration, or the provided plugin object was invalid or `null`/`undefined`.","error":"LTI Storage Plugin not configured."},{"fix":"Manually create the database on your database server *before* running your application, or configure your database user with permissions to create databases if using a dialect that supports automatic database creation (though this is less common for security reasons).","cause":"The database specified in the `Database` constructor ('database' argument) does not exist on the configured database server.","error":"ER_BAD_DB_ERROR: Unknown database 'your_database_name'"}],"ecosystem":"npm"}