Cvmcosta / ltijs

Turn your application into a fully integratable LTI 1.3 tool provider.
https://cvmcosta.github.io/ltijs/
Apache License 2.0
310 stars 71 forks source link

How to define placements and permissions when using dynamic registration? #230

Closed renaatdemuynck closed 2 months ago

renaatdemuynck commented 3 months ago

Hi, I've managed to get my app up-and-running with dynamic registration enabled, but when registering using defaults, only 'Link selection' is available. I searched the documentation on how to define multiple placements, but can't seem to find how to do this...

Tool consumer: Canvas LMS

afbeelding

afbeelding

Any help would be greatly appreciated!

renaatdemuynck commented 3 months ago

I managed to get it working now:

lti.onDynamicRegistration(async (req, res, next) => {
    const message = await lti.DynamicRegistration.register(
        req.query.openid_configuration,
        req.query.registration_token,
        {
            scope: `
                https://purl.imsglobal.org/spec/lti-ags/scope/lineitem
                https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly
                https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly
                https://purl.imsglobal.org/spec/lti-ags/scope/score
                https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly
            `,
            'https://purl.imsglobal.org/spec/lti-tool-configuration': {
                messages: [
                    {
                        type: 'LtiResourceLinkRequest',
                        placements: [
                            'course_navigation',
                            'account_navigation',
                            'global_navigation'
                        ]
                    }
                ]
            }
        }
    );

    res.setHeader('Content-type', 'text/html');
    res.send(message);
});

afbeelding

But now I still haven't figured out how to set different urls for each placement. I looked at the LTI specs but it seems it doesn't provide the possibility to do so...?

renaatdemuynck commented 3 months ago

Finally figured it out:

lti.setup(
    process.env.LTI_KEY,
    {
        url: 'mongodb://' + process.env.LTI_DB_HOST + '/' + process.env.LTI_DB_NAME + '?authSource=admin'
    },
    {
        cookies: {
            secure: true,
            sameSite: 'None'
        },
        devMode: (process.env.NODE_ENV !== 'production'),
        dynReg: {
            url: 'https://xxx-xxx-xxx.ngrok-free.app',
            name: 'LTI Dynamic Registration TEST',
            description: 'LTI Dynamic Registration TEST - Description',
            redirectUris: [
                'https://xxx-xxx-xxx.ngrok-free.app/launch',
                'https://xxx-xxx-xxx.ngrok-free.app/lti/course',
                'https://xxx-xxx-xxx.ngrok-free.app/lti/admin',
            ],
            useDeepLinking: false,
            autoActivate: true
        }
    }
);

lti.onDynamicRegistration(async (req, res, next) => {
    const message = await lti.DynamicRegistration.register(
        req.query.openid_configuration,
        req.query.registration_token,
        {
            scope: `
                https://purl.imsglobal.org/spec/lti-ags/scope/lineitem
                https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly
                https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly
                https://purl.imsglobal.org/spec/lti-ags/scope/score
                https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly
            `,
            'https://purl.imsglobal.org/spec/lti-tool-configuration': {
                messages: [
                    {
                        type: 'LtiResourceLinkRequest',
                        target_link_uri: 'https://xxx-xxx-xxx.ngrok-free.app/lti/course',
                        label: 'LTI TEST Course Placement',
                        'label#en': 'LTI TEST Course Placement',
                        'label#nl': 'LTI TEST Cursus Plaatsing',
                        placements: ['course_navigation'],
                        roles: [
                            'http://purl.imsglobal.org/vocab/lis/v2/membership#Instructor',
                            'http://purl.imsglobal.org/vocab/lis/v2/membership#ContentDeveloper'
                        ]
                    },
                    {
                        type: 'LtiResourceLinkRequest',
                        target_link_uri: 'https://xxx-xxx-xxx.ngrok-free.app/lti/admin',
                        label: 'LTI TEST Account Placement',
                        'label#en': 'LTI TEST Account Placement',
                        'label#nl': 'LTI TEST Account Plaatsing',
                        icon_uri: 'https://xxx-xxx-xxx.ngrok-free.app/assets/logo-icon.png',
                        placements: ['account_navigation', 'global_navigation'],
                        roles: [
                            'http://purl.imsglobal.org/vocab/lis/v2/membership#Administrator'
                        ]
                    }
                ]
            }
        }
    );

    res.setHeader('Content-type', 'text/html');
    res.send(message);
});

afbeelding

afbeelding

renaatdemuynck commented 2 months ago

So, this means that Canvas now fully supports dynamic registration and that everything works as expected. This should be updated in the documentation.Also, it would be great to have more detailed information and examples on how to override the registration options. I'd be happy to add all this to the documentation when I find the time.

renaatdemuynck commented 2 months ago

PS: Blackboard also supports dynamic registration: https://help.blackboard.com/nl-nl/node/45891