npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@byu-oit-sdk/svelte

v0.7.0

Published

Handles auth for byu-oit Svelte-kit web frontends

Readme

@byu-oit-sdk/svelte

Requirements:

  • Node.js 18+
    • or Node.js 10+ with fetch and crypto polyfills
  • npm v9+

Installing

npm install @byu-oit-sdk/svelte

Introduction

Use this module to configure SvelteKit websites that need to implement the OAuth 2.0 Authorization Code grant type. This package requires you to also implement @byu-oit-sdk/session-svelte. See usage examples below.

This module assumes that the access token returned after the authorization code exchange will be a jwt that it can decode to extract user information. This behavior is configurable by passing in the userInfoCallback or getIdToken function into the plugin configuration. A byuOitGetIdToken function is exported which can be used to override the default getIdToken function. The byuOitGetIdToekn function must be used for websites using BYU's API manager.

Options

In addition to the options below, any AuthorizationCodeProvider options may also be passed into the configuration.

| Option | Type | Default | Description | |---------------------|----------|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | logIn | string | /signin | The path which redirects the caller to the authorization url to sign in. | | logInRedirect | string | / | The path to redirect the caller to after signing in. | | logOut | string | /signout | The path to call to clear a user's session and revoke the access token. | | logOutRedirect | string | / | The path to redirect the caller to after signing out. | | errorRedirect | string | /error | The path to redirect the caller to after an error is encountered during the authorization flow. | | userInfoCookieName | string | user_info | The name of the cookie containing the user information parsed from the token. | | sessionIdCookieName | string | sessionId | The name of the cookie where the users session id can be found. If overriding the default, this value must be identical to the value passed in to @byu-oit-sdk/session-svelte | | getIdToken | function | (returns the access token) | Configures how the package gets the id token. | | userInfoCallback | function | (returns the decoded token using the getIdToken function) | Configures how the package gets the user information. | | clientId | string | - | The client identifier issued to the client during the registration process. | | clientSecret | string | - | The client secret of the account being used. Some Oauth providers (such as BYU's API manager) will not require this value, but others, like Okta, will. | | redirectUri | string | - | The redirection endpoint that the authorization server should redirect to after authenticating the resource owner. This can be a relative URL (e.g. /callback) or absolute (e.g. https://somesite.byu.edu/auth/callback) | | discoveryEndpoint | string | - | Used to configure where the user will be sent to sign in. | | scope | string | - | An Oauth property for determining access to data (docs). Set this to open_id when using BYU's API manager. |

Note that any of the parameters of type string can also be defined through environment variables with the BYU_OIT_ prefix.

In the code examples below, if any of the required parameters are not provided it is because environment variables were used instead.

Signing In

  1. For a user to log in, the browser should direct the user to the logIn route.
  2. After the user logs in, the server will redirect the user to the location provided in the redirect query parameter from the login step, or falls back to the logInRedirect option passed into the configuration.
  3. If the user encounters an error, they will be redirected to errorRedirect and an error message will be displayed in the query parameters of the url.

Signing Out

  1. For a user to log out, the browser should direct the user to thelogOut route.
  2. When the user logs out, their session is cleared but the token is not revoked.
  3. After logging out, they will be redirected to the logOutRedirect route.
  4. If the user encounters an error, they will be redirected to errorRedirect and an error message will be displayed in the query parameters of the url.

Usage

There are two functions exported by this package that must be implemented, and there are others that may be implemented to achieve additional functionality.

Install hooks with AuthorizationCodeFlow()

The only piece that absolutely must be implemented is the AuthorizationCodeFlow function which exports a SvelteKit handle function that sets up a series of hooks that handle log-in, log-out, and other authentication functionality. That handle function should be exported as handle through a sequence() call from your hooks.server.ts file so that you can have the handle from @byu-oit-sdk/session-svelte be executed first. See the example below:

import { SessionHandler } from '@byu-oit-sdk/session-svelte'
import { AuthorizationCodeFlow, byuOitGetIdToken as getIdToken } from '@byu-oit-sdk/svelte'
import { sequence } from '@sveltejs/kit/hooks'
import type { Handle } from '@sveltejs/kit'
import env from 'env-var'
import { DynamoDBClient } from '@aws-sdk/client-dynamodb'
import { DynamoSessionStore } from '@byu-oit-sdk/session-dynamo'

export const handle = await (async () => {
  // this file runs (twice!) when running `vite build`, so if we are building, skip this code block.
  // See https://github.com/sveltejs/kit/issues/8795
  if (!building) {
    return sequence()
  }
  // this is one example of how you could dynamically switch between using dynamo and in-memory stores for local and production use.
  const isProduction = env.get('NODE_ENV').default('development').asEnum(['production', 'development']) === 'production'

  let store // if store is undefined (e.g. for local development), an in-memory store will be used
  if (isProduction) {
    const client = new DynamoDBClient({
      region: env.get('AWS_REGION').required().asString()
  })
    store = new DynamoSessionStore({ client, tableName: 'sessions' })
}

  const sessionHandle = await SessionHandler({ store })

  // the SessionHandler handle must be executed before the AuthorizationCodeFlow handle
  return sequence(sessionHandle, AuthorizationCodeFlow({
    redirectUri: '/callback',
    getIdToken
  }))
})()

Oauth data, including information from the decoded token, will now be stored in event.locals.session in server-side SvelteKit functions. For example, here is how you could access it in a request handler in a +server.ts file:

import type {RequestHandler, RequestEvent} from './$types'

export const GET: RequestHandler = async function (event: RequestEvent) {
  const session = event.locals.session.data ?? {}
  if (!session.token.accessToken || !session?.user?.user_id)
    return new Response(JSON.stringify({error: 'No access token'}), {status: 401})
  }
  const accessToken: string = session.token.accessToken

  /* make an api call using the access token */

  return new Response(/* add api call response data here */)
}

Note that the above example assumes that the id token contains a user_id property.

Access SessionHandler Information with topLevelLoad()

In addition to implementing the AuthorizationCodeFlow function in the hooks.server.ts, you should also export topLevelLoad() as load() from your top-level +layout.server.ts file (i.e. src/routes/+layout.server.ts). This function attaches information obtained from the token (i.e. user name and id) to your pagedata so that you can access it easily. SvelteKit is expecting a load() function to be exported from this file, so do not call it anything else.

export { topLevelLoad as load } from '@byu-oit-sdk/svelte'
const { topLevelLoad } = require('@byu-oit-sdk/svelte')
exports.load = topLevelLoad

If you would like to implement your own load functionality in that file, you can define a load() function that executes the imported load function, as shown below:

import { topLevelLoad } from '@byu-oit-sdk/svelte'
import type { LayoutServerLoad } from './$types'

export const load: LayoutServerLoad = (event) => {
  const sessionLoadResults = topLevelLoad(event)

    /* perform custom load functionality */
  const foo = 'bar'

  return { foo /* additional pagedata */, ...sessionLoadResults }
}
const { topLevelLoad } = require('@byu-oit-sdk/svelte')

exports.load = (event) => {
  const sessionLoadResults = topLevelLoad(event)

    /* perform custom load functionality */
  const foo = 'bar'

  return { foo /* additional pagedata */, ...sessionLoadResults }
}

Then, session data can be accessed in your svelte files. For example, a +layout.svelte needing to access your display_name might do something like the following:

<script lang="ts">
    import type { PageData } from './$types'

    export let data: PageData
</script>

{#if data.session.user}
    <span slot="user-name">{data.session.user.display_name}</span>
{/if}

Note that this example depends on the id token including a display_name property.

Protect Sensitive Pages with Required or Automatic Authentication

In order to restrict access to certain pages (requiring users to log-in first), we recommend creating a layout group via a folder whose name is wrapped in parentheses (e.g. (authenticated)) so that all the routes that require the user to be logged-in can be stored in that folder. The parenthesis tell SvelteKit not to use that folder name in the actual path of the route (e.g. /(authenticated)/foo/bar is accessed by navigating to /foo/bar).

Create a +layout.server.ts file at the base of the directory for your protected routes, and in its exported load function check if the user has logged in. If not, then either throw an error, or automatically redirect the user to the login screen with the getLoginUrl function which is added to event.locals by AuthorizationCodeFlow.

import type { LayoutServerLoad } from './$types'
import { redirect } from '@sveltejs/kit'

export const load: LayoutServerLoad = async ({ locals }) => {
   if (locals.session.data.token == null) {
      redirect(302, locals.getLoginUrl('/return_to_me_after_login'))
   }
}

If You Are Using BYUs API Manager...

If you are using calling APIs through BYU's API manager, the default behavior of this package may not work because BYU doesn't use id tokens by default. However, this package exports a byuOitGetIdToken function for this purpose:

import { SessionHandler } from '@byu-oit-sdk/session-svelte'
import { AuthorizationCodeFlow, byuOitGetIdToken } from '@byu-oit-sdk/svelte'
import { sequence } from '@sveltejs/kit/hooks'
import type { Handle } from '@sveltejs/kit'
import env from 'env-var'
import { DynamoDBClient } from '@aws-sdk/client-dynamodb'
import { DynamoSessionStore } from '@byu-oit-sdk/session-dynamo'

export const handle = await (async () => {
  // this file runs (twice!) when running `vite build`, so if we are building, skip this code block.
  // See https://github.com/sveltejs/kit/issues/8795
  if (!building) {
    return sequence()
  }
  // this is one example of how you could dynamically switch between using dynamo and in-memory stores for local and production use.
  const isProduction = env.get('NODE_ENV').default('development').asEnum(['production', 'development']) === 'production'

  let store // if store is undefined (e.g. for local development), an in-memory store will be used
  if (isProduction) {
    const client = new DynamoDBClient({
      region: env.get('AWS_REGION').required().asString()
    })
    store = new DynamoSessionStore({ client, tableName: 'sessions' })
  }


  const sessionHandle = await SessionHandler({ store })

// the SessionHandler handle must be executed before the AuthorizationCodeFlow handle
  return sequence(sessionHandle, AuthorizationCodeFlow({
    redirectUri: '/callback',
    getIdToken: byuOitGetIdToken
  }))
})

Make sure to set your BYU_OIT_SCOPE environment variable to openid when using BYU's API manager.

Logging in and out

This package sets up two ways for users to log in and out. The main way is to have a link that sends the user to the value passed in as logIn or logOut in the AuthorizationCodeFlow({}) function (the default is /signin and /signout, respectively). The user could even manually navigate to those routes in their browser.

<a href="/signout">Sign Out</a>
<a href="/signin">Sign In</a>

If you want to redirect the user to login or logout pages while running server-side code, getLoginUrl and getLogoutUrl functions are added to event.locals by AuthorizationCodeFlow. These functions can be accessed in server-side load() functions in +page.server.ts or +layout.server.ts files.

import type { LayoutServerLoad } from './$types'
import { error, redirect } from '@sveltejs/kit'

export const load: LayoutServerLoad = async (event) => {
   if (event.locals.session == null) {
      error(500, 'No session found')
   }
   if (event.locals.session.data.token == null) {
      redirect(302, event.locals.getLoginUrl('/return_to_me_after_login'))
   }
}

Note on unit tests

The unit tests for this package are run via ava using the Typescript importer tsimp and the Typescript runtime tsx.

  • For Node.js versions v18.19 and higher, the --import=tsimp node argument is included to address an issue where running unit tests results in an error related to package path exports (ERR_PACKAGE_PATH_NOT_EXPORTED).
  • Conversely, for Node.js versions v18.18 and lower, the --loader=tsx node argument is necessary to prevent a TypeError (ERR_UNKNOWN_FILE_EXTENSION) caused by unrecognized file extensions during unit test execution.