Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combining with SvelteKit #171

Open
hades5a opened this issue Dec 16, 2022 · 2 comments
Open

Combining with SvelteKit #171

hades5a opened this issue Dec 16, 2022 · 2 comments

Comments

@hades5a
Copy link

hades5a commented Dec 16, 2022

Hello,
I would like to combine ltijs with SveltKit 1.0. Main problem is preserving the "ltik". Do you have a suggestion for the best architecture?

@hades5a
Copy link
Author

hades5a commented Dec 16, 2022

Issue is that SvelteKit uses Server-Side-Rendering. When accessing different routes ltik is needed. Because we are already on the server I cant access the ltik

@roelvanhintum
Copy link

For anyone else running into this, as a solution i used a custom server.js for dev (hmr won't work) and production instead of adapter-node's own server.js. We've loaded ltijs in serverless mode on a express-js server on a /lti path so sveltekit can run on root.

Production:

import express from 'express';
import { handler } from './build/handler.js';
import { Provider as lti } from 'ltijs';
import router from './lti-router.js';

const app = express();

// Setup
lti.setup(
  process.env.LTI_SECRET,
  {
    url: process.env.MONGO_URL,
    connection: { user: process.env.MONGO_USER, pass: process.env.MONGO_PASS },
  },
  {
    cookies: {
      secure: true,
      sameSite: 'None',
    },
  },
);

// When receiving successful LTI launch redirects to app
lti.onConnect(async (token, req, res) => {
  lti.redirect(res, '/');
});

// Setup function
const setup = async () => {
  await lti.deploy({ serverless: true });

  lti.app.use(router);

  // Mount Ltijs express app into preexisting express app with /lti prefix
  app.use('/lti', lti.app);

  // Use vite's connect instance as middleware. If you use your own
  // express router (express.Router()), you should use router.use
  app.use(handler);

  /**
   * Register platform
   */
  const platform = await lti.registerPlatform({
    url: process.env.LTI_ISSUER,
    name: 'Platform',
    clientId: process.env.LTI_CLIENTID,
    authenticationEndpoint: process.env.LTI_AUTH_REQUEST_URL,
    accesstokenEndpoint: process.env.LTI_ACCESS_TOKEN_URL,
    authConfig: { method: 'JWK_SET', key: process.env.LTI_PUBLIC_KEYSET_URL },
  });

  // Use this to retrieve the public key when not using the /lti/keys endpoint.
  const rsaKey = await platform.platformPublicKey();
  console.log('Platform public rsa key', rsaKey);

  app.listen(3000, () => {
    console.log('listening on port 3000');
  });
};

setup();

Development

import express from 'express';
import { createServer as createViteServer } from 'vite';
import { Provider as lti } from 'ltijs';
import router from './lti-router.js';

const parentServer = express();

// Create Vite server in middleware mode and configure the app type as
// 'custom', disabling Vite's own HTML serving logic so parent server
// can take control
const vite = await createViteServer({
  server: {
    hmr: {
      server: parentServer,
    },
    middlewareMode: true,
  },
  appType: 'custom',
});

// Setup
lti.setup(
  process.env.LTI_SECRET,
  {
    url: process.env.MONGO_URL,
    connection: { user: process.env.MONGO_USER, pass: process.env.MONGO_PASS },
  },
  {
    cookies: {
      secure: false, // Set secure to true if the testing platform is in a different domain and https is being used
      sameSite: '', // Set sameSite to 'None' if the testing platform is in a different domain and https is being used
    },
    devMode: true, // Set DevMode to true if the testing platform is in a different domain and https is not being used
  },
);

// When receiving successful LTI launch redirects to app
lti.onConnect(async (token, req, res) => {
  console.log('token', JSON.stringify(token), token.platformContext.endpoint.scope);
  lti.redirect(res, '/');
});

// Setup function
const setup = async () => {
  await lti.deploy({ serverless: true });

  // Our LTI router goes into the Ltijs app
  lti.app.use(router);

  // Mount Ltijs express app into preexisting express app with /lti prefix
  parentServer.use('/lti', lti.app);

  // Use vite's connect instance as middleware. If you use your own
  // express router (express.Router()), you should use router.use
  parentServer.use(vite.middlewares);
  // parentServer.use((req, res, next) => {
  //   vite.middlewares.handle(req, res, next);
  // });

  /**
   * Register platform
   */
  const platform = await lti.registerPlatform({
    url: process.env.LTI_ISSUER,
    name: 'Platform',
    clientId: process.env.LTI_CLIENTID,
    authenticationEndpoint: process.env.LTI_AUTH_REQUEST_URL,
    accesstokenEndpoint: process.env.LTI_ACCESS_TOKEN_URL,
    authConfig: { method: 'JWK_SET', key: process.env.LTI_PUBLIC_KEYSET_URL },
  });

  // Use this to retrieve the public key when not using the /lti/keys endpoint.
  const rsaKey = await platform.platformPublicKey();
  console.log('Platform public rsa key', rsaKey);

  parentServer.listen(3000, () => {
    console.log('listening on port 3000');
  });
};

setup();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants