mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-02-04 06:22:59 -05:00
rem
This commit is contained in:
@@ -1,268 +0,0 @@
|
||||
# MediaCMS LTI Integration Guide
|
||||
|
||||
This document explains how the TinyMCE MediaCMS plugin integrates with Moodle's LTI (Learning Tools Interoperability) system to provide authenticated access to the MediaCMS video library.
|
||||
|
||||
## Overview
|
||||
|
||||
The plugin uses **LTI 1.3 Deep Linking** to authenticate users with MediaCMS. Instead of implementing LTI authentication directly, the plugin leverages Moodle's built-in LTI module (`/mod/lti/`) to handle the complex OIDC/JWT authentication flow.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ MOODLE (Your Instance) │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────┐ │
|
||||
│ │ TinyMCE Editor │ │ /mod/lti/ │ │ External Tool │ │
|
||||
│ │ MediaCMS Plugin │───▶│ contentitem.php │───▶│ Configuration │ │
|
||||
│ │ (this plugin) │ │ auth.php │ │ (Tool ID: X) │ │
|
||||
│ └─────────────────────┘ └─────────────────────┘ └─────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ LTI 1.3 OIDC Flow
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ MEDIACMS (External Service) │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────┐ │
|
||||
│ │ OIDC Login │ │ LTI Launch │ │ Video Library │ │
|
||||
│ │ /lti/oidc/login/ │───▶│ /lti/launch/ │───▶│ /lti/select/ │ │
|
||||
│ └─────────────────────┘ └─────────────────────┘ └─────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
tiny/plugins/mediacms/
|
||||
├── classes/
|
||||
│ └── plugininfo.php # Backend: Passes LTI config to JavaScript
|
||||
├── amd/src/
|
||||
│ ├── options.js # Frontend: Registers LTI options
|
||||
│ └── iframeembed.js # Frontend: Implements LTI form submission
|
||||
├── settings.php # Admin settings (LTI Tool ID)
|
||||
├── lang/en/
|
||||
│ └── tiny_mediacms.php # Language strings
|
||||
└── LTI_INTEGRATION.md # This file
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
### Step 1: Admin Configuration
|
||||
|
||||
An administrator must configure the LTI Tool ID in:
|
||||
**Site Administration → Plugins → Text editors → TinyMCE → MediaCMS settings**
|
||||
|
||||
The Tool ID corresponds to an External Tool configured in Moodle that points to MediaCMS.
|
||||
|
||||
### Step 2: Backend Preparation (plugininfo.php)
|
||||
|
||||
When the editor loads, `get_lti_configuration()` retrieves:
|
||||
- **toolId**: The External Tool ID from plugin settings
|
||||
- **courseId**: The current course context
|
||||
- **contentItemUrl**: URL to Moodle's `/mod/lti/contentitem.php`
|
||||
|
||||
```php
|
||||
protected static function get_lti_configuration(context $context): array {
|
||||
$ltitoolid = get_config('tiny_mediacms', 'ltitoolid');
|
||||
// ... determine courseId from context ...
|
||||
return [
|
||||
'lti' => [
|
||||
'toolId' => (int) $ltitoolid,
|
||||
'courseId' => $courseid,
|
||||
'contentItemUrl' => '/mod/lti/contentitem.php',
|
||||
],
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Frontend LTI Launch (iframeembed.js)
|
||||
|
||||
When the user clicks "Video Library from Iframe" tab:
|
||||
|
||||
1. **Check LTI config**: If `toolId`, `courseId`, and `contentItemUrl` are set, use LTI flow
|
||||
2. **Create hidden form**: Dynamically create an HTML form targeting the iframe
|
||||
3. **Submit to Moodle LTI**: POST to `/mod/lti/contentitem.php` with tool parameters
|
||||
|
||||
```javascript
|
||||
loadIframeLibraryViaLti(root, ltiConfig) {
|
||||
// Create form targeting the iframe
|
||||
const ltiForm = document.createElement('form');
|
||||
ltiForm.target = iframeName;
|
||||
ltiForm.action = ltiConfig.contentItemUrl;
|
||||
ltiForm.method = 'post';
|
||||
|
||||
// Add LTI parameters
|
||||
const fields = {
|
||||
'id': ltiConfig.toolId,
|
||||
'course': ltiConfig.courseId,
|
||||
'title': '',
|
||||
'text': '',
|
||||
};
|
||||
// ... create hidden inputs and submit ...
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: LTI Authentication Flow
|
||||
|
||||
Moodle's LTI module handles the authentication:
|
||||
|
||||
1. **OIDC Initiate Login**: Moodle POSTs to MediaCMS's OIDC login endpoint
|
||||
2. **Authorization Request**: MediaCMS redirects back to Moodle's `/mod/lti/auth.php`
|
||||
3. **JWT Token Generation**: Moodle creates a signed JWT with user info
|
||||
4. **LTI Launch**: Moodle POSTs the JWT to MediaCMS's launch endpoint
|
||||
5. **Content Selection**: MediaCMS displays the authenticated video library
|
||||
|
||||
### Step 5: Video Selection (postMessage)
|
||||
|
||||
When the user selects a video in MediaCMS, it sends a `postMessage` to the parent window:
|
||||
|
||||
```javascript
|
||||
// MediaCMS sends:
|
||||
window.parent.postMessage({
|
||||
type: 'videoSelected',
|
||||
embedUrl: 'https://mediacms.io/embed/xyz123',
|
||||
videoId: 'xyz123'
|
||||
}, '*');
|
||||
|
||||
// Plugin receives in handleIframeLibraryMessage():
|
||||
if (data.type === 'videoSelected' && data.embedUrl) {
|
||||
this.selectIframeLibraryVideo(root, data.embedUrl, data.videoId);
|
||||
}
|
||||
```
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
### For Administrators
|
||||
|
||||
#### 1. Create External Tool in Moodle
|
||||
|
||||
1. Go to **Site Administration → Plugins → Activity modules → External tool → Manage tools**
|
||||
2. Click **"Configure a tool manually"**
|
||||
3. Fill in the following:
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| Tool name | MediaCMS Video Library |
|
||||
| Tool URL | `https://lti.mediacms.io/lti/launch/` |
|
||||
| LTI version | LTI 1.3 |
|
||||
| Public keyset URL | `https://lti.mediacms.io/.well-known/jwks.json` |
|
||||
| Initiate login URL | `https://lti.mediacms.io/lti/oidc/login/` |
|
||||
| Redirection URI(s) | `https://lti.mediacms.io/lti/launch/` |
|
||||
| Content Selection URL | `https://lti.mediacms.io/lti/select-media/` |
|
||||
| Supports Deep Linking | ✓ Yes |
|
||||
|
||||
4. Save and note the **Tool ID** (visible in URL when editing: `id=X`)
|
||||
|
||||
#### 2. Register Moodle with MediaCMS
|
||||
|
||||
Contact MediaCMS administrator with:
|
||||
- **Platform ID (Issuer)**: Your Moodle URL (e.g., `https://moodle.example.com`)
|
||||
- **Client ID**: Generated by Moodle after creating the tool
|
||||
- **Public Keyset URL**: `https://moodle.example.com/mod/lti/certs.php`
|
||||
- **Access Token URL**: `https://moodle.example.com/mod/lti/token.php`
|
||||
- **Authentication Request URL**: `https://moodle.example.com/mod/lti/auth.php`
|
||||
|
||||
#### 3. Configure Plugin Settings
|
||||
|
||||
1. Go to **Site Administration → Plugins → Text editors → TinyMCE → MediaCMS settings**
|
||||
2. Enter the **Tool ID** from step 1
|
||||
3. Save changes
|
||||
|
||||
### For Developers
|
||||
|
||||
#### Adding Debug Logging
|
||||
|
||||
The code includes console.log statements (guarded by eslint-disable):
|
||||
|
||||
```javascript
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('loadIframeLibrary called, LTI config:', ltiConfig);
|
||||
```
|
||||
|
||||
Check browser console for:
|
||||
- `loadIframeLibrary called, LTI config: {...}` - Shows if LTI config is received
|
||||
- `Submitting LTI form to: ...` - Shows form submission
|
||||
- `LTI iframe loaded` - Shows iframe load event
|
||||
|
||||
#### Testing Without LTI
|
||||
|
||||
If LTI is not configured (toolId = 0), the plugin falls back to static URL loading:
|
||||
|
||||
```javascript
|
||||
if (ltiConfig?.toolId && ltiConfig?.courseId && ltiConfig?.contentItemUrl) {
|
||||
this.loadIframeLibraryViaLti(root, ltiConfig);
|
||||
} else {
|
||||
this.loadIframeLibraryStatic(root); // Fallback
|
||||
}
|
||||
```
|
||||
|
||||
#### Rebuilding JavaScript
|
||||
|
||||
After modifying AMD modules, rebuild with:
|
||||
|
||||
```bash
|
||||
# Ensure Node.js 22.x is active
|
||||
nvm use 22
|
||||
|
||||
# Run grunt from Moodle root
|
||||
cd /path/to/moodle
|
||||
grunt amd
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Nothing happens when clicking Video Library tab"
|
||||
|
||||
1. **Check LTI Tool ID**: Go to plugin settings and verify Tool ID is set
|
||||
2. **Check browser console**: Look for `loadIframeLibrary` logs
|
||||
3. **Verify External Tool exists**: Ensure the Tool ID corresponds to a valid tool
|
||||
4. **Check course context**: LTI requires a valid course ID (not site level)
|
||||
|
||||
### "LTI authentication fails"
|
||||
|
||||
1. **Verify MediaCMS registration**: Moodle must be registered as a platform in MediaCMS
|
||||
2. **Check URLs**: Ensure all LTI URLs are correct and accessible
|
||||
3. **Check HTTPS**: LTI 1.3 requires HTTPS on both ends
|
||||
4. **Review Moodle logs**: Check `Site Administration → Reports → Logs` for LTI errors
|
||||
|
||||
### "Video selection doesn't work"
|
||||
|
||||
1. **Check postMessage handling**: Verify MediaCMS sends expected message format
|
||||
2. **Check browser console**: Look for `handleIframeLibraryMessage` logs
|
||||
3. **Verify origin**: Some browsers block cross-origin postMessages
|
||||
|
||||
## Message Formats Supported
|
||||
|
||||
The plugin handles multiple postMessage formats:
|
||||
|
||||
```javascript
|
||||
// Custom format
|
||||
{ type: 'videoSelected', embedUrl: '...', videoId: '...' }
|
||||
|
||||
// LTI Deep Linking format
|
||||
{ type: 'ltiDeepLinkingResponse', content_items: [...] }
|
||||
|
||||
// MediaCMS specific
|
||||
{ action: 'selectMedia', embedUrl: '...', mediaId: '...' }
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **LTI 1.3 Security**: All authentication uses signed JWTs and OIDC
|
||||
2. **No credentials in plugin**: The plugin never handles user credentials
|
||||
3. **Moodle handles auth**: All sensitive operations go through Moodle's LTI module
|
||||
4. **postMessage validation**: Consider adding origin checks for production
|
||||
|
||||
## References
|
||||
|
||||
- [LTI 1.3 Specification](https://www.imsglobal.org/spec/lti/v1p3)
|
||||
- [Moodle LTI Documentation](https://docs.moodle.org/en/LTI_and_Moodle)
|
||||
- [Moodle External Tool](https://docs.moodle.org/en/External_tool)
|
||||
|
||||
## Contributing
|
||||
|
||||
When modifying LTI-related code:
|
||||
|
||||
1. Test with a real LTI tool (not just mocks)
|
||||
2. Test in multiple browsers (postMessage behavior varies)
|
||||
3. Test both with and without LTI configured (fallback path)
|
||||
4. Update this documentation if behavior changes
|
||||
Reference in New Issue
Block a user