Skip to content
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d52c871
Add LTI tables
cj-young May 22, 2026
7ca3ccc
Abstract API key encryption
cj-young May 22, 2026
53360f8
Add CLI to create registration
cj-young May 22, 2026
c9dffdf
Add missing LTI repositories
cj-young May 22, 2026
fb7963c
Add institution-registration relationship
cj-young May 27, 2026
16c348d
Move all LMS config info to registration table
cj-young May 28, 2026
d18e4f8
Add file-based LTI registration initiation
cj-young May 28, 2026
ae9d9d5
Fix registration command using wrong IO class
cj-young May 28, 2026
1b7a276
Replace LTI and OAuth URLs with DB endpoints
cj-young May 28, 2026
2682de9
Merge branch 'dev' into issue/1193-lti_tables
cj-young May 28, 2026
75a51f5
Allow registration command to be stopped
cj-young May 29, 2026
455fd4c
Add conditional keyset generation in registration
cj-young May 29, 2026
25f603f
Fix registration command comma syntax error
cj-young May 29, 2026
8d49868
Fix tab width inconsistencies
cj-young May 29, 2026
bbf9b4e
Add documentation comments
cj-young May 29, 2026
c1258d7
Add encryption to signing key private key column
cj-young May 29, 2026
2745d31
Add unique constraint to registration client ID and iss
cj-young Jun 2, 2026
1bf2060
Fix login auth endpoint prompt missing
cj-young Jun 2, 2026
a4ff739
Remove JSON support for registration command
cj-young Jun 2, 2026
35f3b7e
Update docs to describe registration steps
cj-young Jun 2, 2026
a49b2ae
Remove `JWK_BASE_URL` from instructions and env files
cj-young Jun 2, 2026
fcc35cb
Squash LTI table migrations
cj-young Jun 2, 2026
5971347
Update .gitignore to exclude institution YAML config
cj-young Jun 2, 2026
697fb03
Remove old institution make scripts
cj-young Jun 2, 2026
6e675ec
Update Heroku README
cj-young Jun 2, 2026
036a10b
Remove Devhub from institution presets
cj-young Jun 3, 2026
ed4339e
Remove logger
cj-young Jun 4, 2026
7e1f70d
Merge branch 'dev' into issue/1193-lti_tables
cj-young Jun 16, 2026
9185fef
Fix incorrect variable reference
cj-young Jun 17, 2026
6de192d
Separate GET and POST params in LTI launch login
cj-young Jun 17, 2026
a949ad5
Merge branch 'dev' into issue/1193-lti_tables
cj-young Jun 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,6 @@ VIMEO_API_KEY=""
YOUTUBE_API_KEY=""
###> api keys ###

###> jwk base url ###
JWK_BASE_URL="https://canvas.instructure.com/"
###> jwk base url ###

############# Admin Panel Data Retrieval Params:

###> admin panel retrieval task lms url ###
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ yarn-error.log
.phpunit.result.cache
###< phpunit/phpunit ###

###> YAML ###
*.secret.yaml
*.secret.yml
###< YAML ###

*.env
13 changes: 2 additions & 11 deletions HEROKU.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ Click the Heroku button and follow the instructions below:
* `canvas` if you are using the Canvas LMS.
* `d2l` if you are using the D2l Brightspace LMS.
5. Fill out the `BASE_URL` field with `https://yourapp.herokuapp.com`. (Replace 'yourapp' with the name you gave in step 1.2.)
6. Fill out the `JWK_BASE_URL` field with the URL to your LMS. The default value works for instructure hosted instances of Canvas, but will need to be modified if your JWK configuration is hosted at a different domain than `iss`.
7. Click the Deploy button and wait for the process to complete.
6. Click the Deploy button and wait for the process to complete.

The above deploy uses the Heroku Postgres Mini plan by default. Please check `https://elements.heroku.com/addons/heroku-postgresql` for Heroku Postgresql plan details. You can upgrade Postgresql plan inside Heroku UI later.

Expand All @@ -36,15 +35,7 @@ php bin/console doctrine:migrations:migrate
php bin/console cache:warmup --env=prod
```
6. Set up developer keys according to the instructions in INSTALL_\<LMS\>.md.
7. Access the Postgres database by running the following command in the Console:
```sql
psql <the DATABASE_URL located in your config vars under the Settings tab>
```
6. Insert your institution in to the institution table as described in INSTALL_\<LMS\>.md. It may be something like:
```sql
INSERT INTO institution (id, title, lms_domain, lms_id, lms_account_id, created, status, vanity_url, metadata, api_client_id, api_client_secret) VALUES (0, 'Canvas', 'myinstitution.instructure.com', 'canvas', '1', '2021-10-21', true, 'vanity.example.com', '{"lang":"en"}', '123456', 'abcdefghijklmnopqrstuvwxyz');
```
(DO NOT copy that command and use it as-is!)
7. Insert your institution data into the database as described in INSTALL_\<LMS\>.md.

### Step 3: Finish
Install the app following the instructions described in INSTALL_\<LMS\>.md.
Expand Down
1 change: 0 additions & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ This command copies the `.env.example` into `.env`, creating the `.env` file in
- `BASE_URL`: If you are hosting UDOIT on Docker or your local machine, leave it as it is. Otherwise, change it to the URL of your instance of UDOIT.
- `WEBPACK_PUBLIC_PATH`: Uf you are hosting UDOIT on Docker or your local machine, leave it as it is. Otherwise, change it to match the `BASE_URL`in such a way that `/build` is located at the root of the `BASE_URL` (Example: If your `BASE_URL` is set to `http://127.0.0.1:8000`, your `WEBPACK_PUBLIC_PATH` should be `/build`).
- `APP_LMS`: `canvas` for Canvas LMS. `d2l` for D2l Brightspace LMS.
- `JWK_BASE_URL`: If you are self-hosting Canvas, you may set it to the URL of your instance of Canvas. (Example: `JWK_BASE_URL="https://canvas.dev.myschool.edu"`)
- `DEFAULT_LANG`: (optional) `en` for English. `es` for Spanish. This is English by default.

## Installation
Expand Down
74 changes: 48 additions & 26 deletions INSTALL_CANVAS.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,36 +115,58 @@ Follow the steps below, replacing `<YOUR_UDOIT_BASE_URL>` with the `BASE_URL` va
4. Click Save.
5. Click `ON` to enable the newly created key.

## Update the Institutions Table
UDOIT is built to support more than one LMS instance. For this purpose, we have an `institution` table that must be populated with the LMS information.
## Add institution data to the database

1. Inside the UDOIT directory, run `cp .ins.env.example .ins.env`
2. open `.ins.env` with a text editor (i.e. Notepad, VS Code, etc.)
UDOIT is built to support more than one LMS instance. There are two supported methods to populating the database with institution data.

### Method 1 (recommended): Create a configuration file

1. Inside the UDOIT directory, run
```bash
cp institution.example.yaml institution.secret.yaml
```
2. Open `institution.secret.yaml` in a text editor (i.e. Notepad, VS Code, etc.)
3. Fill in the fields with the appropriate values
- `TITLE` = Your institution's name
- `LMS_DOMAIN` = The Canvas domain name of your institution (i.e. `myschool.instructure.com`)
- `LMS_ID` = `canvas`
- `LMS_ACCOUNT_ID` = The Canvas account ID (as a string) where UDOIT will be installed
- `CREATED` = Date in this format: `2021-06-08`
- `STATUS` = `1` if you are using MySQL or MariaDB (or Docker), `true` if you are using PostgreSQL
- `VANITY_URL` = Your LMS vanity URL (i.e. `canvas.myschool.edu`)
- `METADATA` = Optional. Institution-specific settings, such as language or excluded tests. Text representation of a JSON object. (i.e. `{"lang":"en"}`)
- `API_CLIENT_ID` = The ID of the developer API key you created earlier
- `API_CLIENT_SECRET` = The secret for the API key you created earlier

With all the values now set up, you're ready to run the command that will automate the creation of your `institutions` table! Run the following command if you have a MySQL database setup:
```
make ins-mysql
```
Or this one if you have a PostgreSQL setup:
```
make ins-psql
```
Your database should now show a new row in the `institution` table, containing all the values you input above.

- `title`: Your institution's name
- `lms_domain`: The Canvas domain name of your institution (i.e. `myschool.instructure.com`)
- `vanity_url`: Your LMS vanity URL (i.e. `canvas.myschool.edu`)
- `lms_id`: MUST be `canvas`
- `lms_account_id`: The Canvas account ID (as a string) where UDOIT will be installed
- `lti_client_id`: The ID of the developer LTI key you created earlier
- `api_client_id`: The ID of the developer API key you created earlier
- `api_client_secret`: The secret for the API key you created earlier
- `platform`: Can be one of two options
- Manual entry; specify the following fields
- `issuer` - The token issuer of your LMS (usually `https://canvas.instructure.com` unless in a test or beta environment)
- `login_auth_endpoint` - The redirect endpoint specified in your LMS (usually `https://sso.canvaslms.com/api/lti/authorize_redirect` if hosted by Canvas)
- `service_auth_endpoint` - The OAuth token endpoint of your LMS (usually `https://sso.canvaslms.com/login/oauth2/token` if hosted by Canvas)
- `service_login_endpoint` - The OAuth login endpoint of your LMS (usually `https://sso.canvaslms.com/login/oauth2/auth` if hosted by Canvas). This is the endpoint that the user will be redirected to during the OAuth process to request consent to use their Canvas API key with the tool
- `jwk_endpoint` - The JWK endpoint of your LMS (usually `https://sso.canvaslms.com/api/lti/security/jwks` if hosted by Canvas)
- Use a preset
- Add a single field called `preset` and populate it with one of the following supported preset options: `Production Canvas`, `Test Canvas`, `Beta Canvas`
- For example, your `platform` field may look like:
```yaml
platform:
preset: Test Canvas
```
- `keyset` Can be one of two options
- Specify the following field
- `generate`: If this field is set to `true`, a new signing keyset will be generated without exception. If it is `false`, the institution's keyset will be set to the keyset in the database with the smallest ID. If no keyset exists, a new one will be created. Use `generate: false` for every institution if you do not want different signing key sets for every institution
- `existing_id`: The database ID of the keyset that you want to reuse
1. Run the following command in the UDOIT directory to populate the databse with your institution data
```bash
make create-registration FILE="institution.secret.yaml"
```

### Method 2: Manual entry through the CLI

## .ENV Setup
For cloud-hosted canvas instances, the default value for the `JWK_BASE_URL` environmental variable will work out of the box. If you are not cloud-hosted, you may need to change the value of this variable in `.env.local` to match your canvas instance.
1. Inside the UDOIT directory, run

```bash
make create-registration
```
2. Follow the prompts and input required information. You will have to input the same information as required in the file-based initialization but will not have easy access to previously entered information both during and after the process, so using this option is not recommended. It remains an option for temporary or testing purposes.

---
## Install the App
Expand Down
72 changes: 41 additions & 31 deletions INSTALL_D2L.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,39 +37,49 @@ UDOIT uses LTI 1.3 to integrate with the LMS.


---
## Update the Institutions Table
UDOIT is built to support more than one LMS instance. For this purpose we have an `institution` table that must be populated with the LMS information.
## Add institution data to the database

**Note:** This step requires knowledge of MySQL.
UDOIT is built to support more than one LMS instance. There are two supported methods to populating the database with institution data.

The following fields need to be populated in the `institution` table.
* title
* Your institution's name
* lms_domain
* The D2L domain name of your institution.
* Do not include `https://` or a trailing slash.
* Example: `myschool.d2l.com`
* lms_id
* `d2l`
* lms_account_id
* The D2L org unit ID where UDOIT will be installed.
* created
* Date in this format: `"2021-06-08"`
* status
* `1` if you are using MySQL or MariaDB
* `true` if you are using PostgreSQL
* vanity_url
* Your LMS vanity URL
* Example: `d2l.myschool.edu`
* metadata
* Optional
* Institution specific settings, such as language or excluded tests.
* Text representation of a JSON object.
* Example: `'{"lang":"es"}'`
* Currently supported languages are English (en) and Spanish (es).
* api_client_id
* api_client_secret
* This key will be encrypted and stored as encrypted on the first use of the key.
### Method 1 (recommended): Create a configuration file

1. Inside the UDOIT directory, run
```bash
cp institution.example.yaml institution.secret.yaml
```
2. Open `institution.secret.yaml` in a text editor (i.e. Notepad, VS Code, etc.)
3. Fill in the fields with the appropriate values
- `title`: Your institution's name
- `lms_domain`: The D2L domain name of your institution (i.e. `myschool.brightspace.com`)
- `vanity_url`: Your LMS vanity URL (i.e. `d2l.myschool.edu`)
- `lms_id`: MUST be `d2l`
- `lms_account_id`: The D2L org unit ID where UDOIT will be installed.
- `lti_client_id`: The ID of the developer LTI key you created earlier
- `api_client_id`: The ID of the developer API key you created earlier
- `api_client_secret`: The secret for the API key you created earlier
- `platform`: Specify the following fields inside the platform field
- `issuer` - The token issuer of your LMS (usually `https://<tenant>.brightspace.com`)
- `login_auth_endpoint` - The redirect endpoint specified in your LMS (usually `https://<tenant>.brightspace.com/d2l/lti/authenticate`)
- `service_auth_endpoint` - The OAuth token endpoint of your LMS (usually `https://auth.brightspace.com/core/connect/token`)
- `service_login_endpoint` - The OAuth login endpoint of your LMS (usually `https://auth.brightspace.com/oauth2/auth`). This is the endpoint that the user will be redirected to during the OAuth process to request consent to use their D2L API key with the tool
- `jwk_endpoint` - The JWK endpoint of your LMS (usually `https://<tenant>.brightspace.com/d2l/.well-known/jwks`)
- `keyset` Can be one of two options
- Specify the following field
- `generate`: If this field is set to `true`, a new signing keyset will be generated without exception. If it is `false`, the institution's keyset will be set to the keyset in the database with the smallest ID. If no keyset exists, a new one will be created. Use `generate: false` for every institution if you do not want different signing key sets for every institution
- `existing_id`: The database ID of the keyset that you want to reuse
4. Run the following command in the UDOIT directory to populate the databse with your institution data
```bash
make create-registration FILE="institution.secret.yaml"
```

### Method 2: Manual entry through the CLI

1. Inside the UDOIT directory, run

```bash
make create-registration
```
2. Follow the prompts and input required information. You will have to input the same information as required in the file-based initialization but will not have easy access to previously entered information both during and after the process, so using this option is not recommended. It remains an option for temporary or testing purposes.

---
## Install the App
Expand Down
26 changes: 3 additions & 23 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
# checks if .ins.env exists and includes it
ifneq (,$(wildcard ./.ins.env))
include .ins.env
export
endif

# ──────────────────────────────────────────────
# Variables
# ──────────────────────────────────────────────
Expand Down Expand Up @@ -87,24 +81,10 @@ admin-panel-retrieve-data: clean-cache
exit 1; \
fi
$(COMPOSE) run --rm php php bin/console app:admin-panel-retrieval $(foreach table,$(TABLES),--tables=$(table))

# ──────────────────────────────────────────────
# Institution Seeding
# ──────────────────────────────────────────────

## Insert institution row (MySQL)
## Reads variables from .ins.env
ins-mysql:
docker exec -it udoit3-db mysql -u root -proot udoit3 \
-e "INSERT INTO institution \
(title, lms_domain, lms_id, lms_account_id, created, status, vanity_url, metadata, api_client_id, api_client_secret) \
VALUES \
('$(TITLE)', '$(LMS_DOMAIN)', '$(LMS_ID)', '$(LMS_ACCOUNT_ID)', '$(CREATED)', '$(STATUS)', '$(VANITY_URL)', '$(METADATA)', '$(API_CLIENT_ID)', '$(API_CLIENT_SECRET)');"

## Insert institution row (PostgreSQL)
## Reads variables from .ins.env
ins-psql:
docker exec -it -e PGPASSWORD=root udoit3-db psql -U root -d udoit3 -w \
-c "INSERT INTO institution \
(title, lms_domain, lms_id, lms_account_id, created, status, vanity_url, metadata, api_client_id, api_client_secret) \
VALUES \
('$(TITLE)', '$(LMS_DOMAIN)', '$(LMS_ID)', '$(LMS_ACCOUNT_ID)', '$(CREATED)', '$(STATUS)', '$(VANITY_URL)', '$(API_CLIENT_ID)', '$(API_CLIENT_SECRET)');"
create-registration:
$(COMPOSE) run --rm php php bin/console app:create-registration $(if $(FILE),--file=$(FILE),)
4 changes: 0 additions & 4 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@
"description": "Full URL to your instance.",
"value": "https://your.herokuapp.com"
},
"JWK_BASE_URL": {
"description": "Overrides `iss` to use an alternative url for JWK. Leave empty if using cloud hosted Canvas.",
"value": ""
},
"HEROKU_TIMEOUT": {
"description": "Web requests time out at 30 seconds causing the app to crash. Value should be significantly less than 30 to prevent this.",
"value": "15"
Expand Down
2 changes: 2 additions & 0 deletions build/nginx/Dockerfile.php.pdo.mysql
Comment thread
mbusch3 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ FROM php:8.5-fpm
# PHP extensions
RUN apt-get update && apt-get install -y libpng-dev zlib1g-dev git unzip
RUN docker-php-ext-install gd pdo pdo_mysql
RUN docker-php-ext-configure pcntl --enable-pcntl \
&& docker-php-ext-install pcntl;
3 changes: 3 additions & 0 deletions docker-compose.nginx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ services:
build:
context: ./build/nginx
dockerfile: Dockerfile.php.pdo.mysql
depends_on:
db:
condition: service_started
volumes:
- ./:/var/www/html
- type: bind
Expand Down
16 changes: 16 additions & 0 deletions institution.example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
title: My School
lms_domain: myschool.instructure.com
vanity_url: webcourses.myschool.edu
lms_id: canvas
lms_account_id: "123"
lti_client_id: my_lti_client_id
api_client_id: my_api_client_id
api_client_secret: super_secret_client_secret
platform:
issuer: https://canvas.instructure.com
login_auth_endpoint: https://sso.canvaslms.com/api/lti/authorize_redirect
service_auth_endpoint: https://sso.canvaslms.com/login/oauth2/token
service_login_endpoint: https://sso.canvaslms.com/login/oauth2/auth
jwk_endpoint: https://sso.canvaslms.com/api/lti/security/jwks
keyset:
generate: false
Loading
Loading