Socket
Socket
Sign inDemoInstall

@workos-inc/authkit-remix

Package Overview
Dependencies
Maintainers
0
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@workos-inc/authkit-remix - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

5

dist/cjs/authkit-callback-route.js

@@ -15,5 +15,3 @@ "use strict";

const state = url.searchParams.get('state');
const returnPathname = state
? JSON.parse(atob(state)).returnPathname
: null;
const returnPathname = state ? JSON.parse(atob(state)).returnPathname : null;
if (code) {

@@ -37,2 +35,3 @@ try {

impersonator,
headers: {},
});

@@ -39,0 +38,0 @@ const session = await (0, cookie_js_1.getSession)(cookie_js_1.cookieName);

4

dist/cjs/cookie.js

@@ -18,5 +18,3 @@ "use strict";

// act as the actual time-limited aspects of the session.
maxAge: env_variables_js_1.WORKOS_COOKIE_MAX_AGE
? parseInt(env_variables_js_1.WORKOS_COOKIE_MAX_AGE, 10)
: 60 * 60 * 24 * 400,
maxAge: env_variables_js_1.WORKOS_COOKIE_MAX_AGE ? parseInt(env_variables_js_1.WORKOS_COOKIE_MAX_AGE, 10) : 60 * 60 * 24 * 400,
secrets: [env_variables_js_1.WORKOS_COOKIE_PASSWORD],

@@ -23,0 +21,0 @@ };

@@ -12,5 +12,3 @@ "use strict";

redirectUri: env_variables_js_1.WORKOS_REDIRECT_URI,
state: returnPathname
? btoa(JSON.stringify({ returnPathname }))
: undefined,
state: returnPathname ? btoa(JSON.stringify({ returnPathname })) : undefined,
screenHint,

@@ -17,0 +15,0 @@ });

import { authLoader } from './authkit-callback-route.js';
import { withAuth } from './session.js';
import { authkitLoader } from './session.js';
import { getSignInUrl, getSignUpUrl, signOut } from './auth.js';
export { authLoader, getSignInUrl, getSignUpUrl, signOut, withAuth, };
export { authLoader, getSignInUrl, getSignUpUrl, signOut, authkitLoader, };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withAuth = exports.signOut = exports.getSignUpUrl = exports.getSignInUrl = exports.authLoader = void 0;
exports.authkitLoader = exports.signOut = exports.getSignUpUrl = exports.getSignInUrl = exports.authLoader = void 0;
const authkit_callback_route_js_1 = require("./authkit-callback-route.js");
Object.defineProperty(exports, "authLoader", { enumerable: true, get: function () { return authkit_callback_route_js_1.authLoader; } });
const session_js_1 = require("./session.js");
Object.defineProperty(exports, "withAuth", { enumerable: true, get: function () { return session_js_1.withAuth; } });
Object.defineProperty(exports, "authkitLoader", { enumerable: true, get: function () { return session_js_1.authkitLoader; } });
const auth_js_1 = require("./auth.js");

@@ -9,0 +9,0 @@ Object.defineProperty(exports, "getSignInUrl", { enumerable: true, get: function () { return auth_js_1.getSignInUrl; } });

@@ -14,19 +14,4 @@ import { User } from '@workos-inc/node';

impersonator?: Impersonator;
headers: Record<string, string>;
}
export interface UserInfo {
user: User;
sessionId: string;
organizationId?: string;
role?: string;
permissions?: string[];
impersonator?: Impersonator;
accessToken: string;
}
export interface NoUserInfo {
user: null;
sessionId?: undefined;
organizationId?: undefined;
role?: undefined;
impersonator?: undefined;
}
export interface AccessToken {

@@ -42,9 +27,23 @@ sid: string;

}
export interface AuthkitMiddlewareAuth {
enabled: boolean;
unauthenticatedPaths: string[];
}
export interface AuthkitMiddlewareOptions {
export interface AuthKitLoaderOptions {
ensureSignedIn?: boolean;
debug?: boolean;
middlewareAuth?: AuthkitMiddlewareAuth;
}
export interface AuthorizedData {
user: User;
sessionId: string;
accessToken: string;
organizationId: string | null;
role: string | null;
permissions: string[];
impersonator: Impersonator | null;
}
export interface UnauthorizedData {
user: null;
sessionId: null;
accessToken: null;
organizationId: null;
role: null;
permissions: null;
impersonator: null;
}

@@ -1,12 +0,21 @@

import { NoUserInfo, Session, UserInfo } from './interfaces.js';
import type { LoaderFunctionArgs, TypedResponse } from '@remix-run/node';
import type { AuthorizedData, UnauthorizedData, AuthKitLoaderOptions, Session } from './interfaces.js';
declare function encryptSession(session: Session): Promise<string>;
declare function withAuth(request: Request, options?: {
ensureSignedIn?: false;
debug?: boolean;
}): Promise<UserInfo | NoUserInfo>;
declare function withAuth(request: Request, options: {
ensureSignedIn?: true;
debug?: boolean;
}): Promise<UserInfo>;
declare function terminateSession(request: Request): Promise<import("@remix-run/node").TypedResponse<never>>;
export { encryptSession, withAuth, terminateSession };
type LoaderValue<Data> = Response | TypedResponse<Data> | NonNullable<Data> | null;
type LoaderReturnValue<Data> = Promise<LoaderValue<Data>> | LoaderValue<Data>;
type AuthLoader<Data> = (args: LoaderFunctionArgs & {
auth: AuthorizedData | UnauthorizedData;
}) => LoaderReturnValue<Data>;
type AuthorizedAuthLoader<Data> = (args: LoaderFunctionArgs & {
auth: AuthorizedData;
}) => LoaderReturnValue<Data>;
declare function authkitLoader(loaderArgs: LoaderFunctionArgs, options: AuthKitLoaderOptions & {
ensureSignedIn: true;
}): Promise<TypedResponse<AuthorizedData>>;
declare function authkitLoader(loaderArgs: LoaderFunctionArgs, options?: AuthKitLoaderOptions): Promise<TypedResponse<AuthorizedData | UnauthorizedData>>;
declare function authkitLoader<Data = unknown>(loaderArgs: LoaderFunctionArgs, loader: AuthorizedAuthLoader<Data>, options: AuthKitLoaderOptions & {
ensureSignedIn: true;
}): Promise<TypedResponse<Data & AuthorizedData>>;
declare function authkitLoader<Data = unknown>(loaderArgs: LoaderFunctionArgs, loader: AuthLoader<Data>, options?: AuthKitLoaderOptions): Promise<TypedResponse<Data & (AuthorizedData | UnauthorizedData)>>;
declare function terminateSession(request: Request): Promise<TypedResponse<never>>;
export { encryptSession, terminateSession, authkitLoader };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.terminateSession = exports.withAuth = exports.encryptSession = void 0;
exports.authkitLoader = exports.terminateSession = exports.encryptSession = void 0;
const node_1 = require("@remix-run/node");

@@ -39,2 +39,3 @@ const env_variables_js_1 = require("./env-variables.js");

impersonator: session.impersonator,
headers: {},
};

@@ -44,3 +45,5 @@ // Encrypt session with new access and refresh tokens

updatedSession.set('jwt', await encryptSession(newSession));
await (0, cookie_js_1.commitSession)(updatedSession);
newSession.headers = {
'Set-Cookie': await (0, cookie_js_1.commitSession)(updatedSession),
};
return newSession;

@@ -63,3 +66,7 @@ }

exports.encryptSession = encryptSession;
async function withAuth(request, { ensureSignedIn = false, debug = false } = {}) {
async function authkitLoader(loaderArgs, loaderOrOptions, options = {}) {
var _a;
const loader = typeof loaderOrOptions === 'function' ? loaderOrOptions : undefined;
const { ensureSignedIn = false, debug = false } = typeof loaderOrOptions === 'object' ? loaderOrOptions : options;
const { request } = loaderArgs;
const session = await updateSession(request, debug);

@@ -76,21 +83,57 @@ if (!session) {

}
return { user: null };
const auth = {
user: null,
accessToken: null,
impersonator: null,
organizationId: null,
permissions: null,
role: null,
sessionId: null,
};
return await handleAuthLoader(loader, loaderArgs, auth);
}
const { sid: sessionId, org_id: organizationId, role, permissions } = (0, jose_1.decodeJwt)(session.accessToken);
return {
const { sessionId, organizationId = null, role = null, permissions = [], } = getClaimsFromAccessToken(session.accessToken);
const auth = {
user: session.user,
sessionId,
user: session.user,
accessToken: session.accessToken,
organizationId,
role,
permissions,
impersonator: session.impersonator,
accessToken: session.accessToken,
impersonator: (_a = session.impersonator) !== null && _a !== void 0 ? _a : null,
};
return await handleAuthLoader(loader, loaderArgs, auth, session);
}
exports.withAuth = withAuth;
exports.authkitLoader = authkitLoader;
async function handleAuthLoader(loader, args, auth, session) {
if (!loader) {
return (0, node_1.json)(auth, session ? { headers: { ...session.headers } } : undefined);
}
// If there's a custom loader, get the resulting data and return it with our
// auth data plus session cookie header
const loaderResult = await loader({ ...args, auth: auth });
if (loaderResult instanceof Response) {
// If the result is a redirect, return it unedited
if (loaderResult.status >= 300 && loaderResult.status < 400) {
return loaderResult;
}
const newResponse = new Response(loaderResult.body, loaderResult);
const data = await newResponse.json();
// Set the content type in case the user returned a Response instead of the
// json helper method
newResponse.headers.set('Content-Type', 'application/json; charset=utf-8');
if (session) {
newResponse.headers.append('Set-Cookie', session.headers['Set-Cookie']);
}
return (0, node_1.json)({ ...data, ...auth }, newResponse);
}
// If the loader returns a non-Response, assume it's a data object
return (0, node_1.json)({ ...loaderResult, ...auth }, session ? { headers: { ...session.headers } } : undefined);
}
async function terminateSession(request) {
const { sessionId } = await withAuth(request);
const cookieSession = await (0, cookie_js_1.getSession)(request.headers.get('Cookie'));
const encryptedSession = await (0, cookie_js_1.getSession)(request.headers.get('Cookie'));
const { accessToken } = (await getSessionFromCookie(request.headers.get('Cookie'), encryptedSession));
const { sessionId } = getClaimsFromAccessToken(accessToken);
const headers = {
'Set-Cookie': await (0, cookie_js_1.destroySession)(cookieSession),
'Set-Cookie': await (0, cookie_js_1.destroySession)(encryptedSession),
};

@@ -107,4 +150,15 @@ if (sessionId) {

exports.terminateSession = terminateSession;
async function getSessionFromCookie(cookie) {
const session = await (0, cookie_js_1.getSession)(cookie);
function getClaimsFromAccessToken(accessToken) {
const { sid: sessionId, org_id: organizationId, role, permissions } = (0, jose_1.decodeJwt)(accessToken);
return {
sessionId,
organizationId,
role,
permissions,
};
}
async function getSessionFromCookie(cookie, session) {
if (!session) {
session = await (0, cookie_js_1.getSession)(cookie);
}
if (session.has('jwt')) {

@@ -111,0 +165,0 @@ return (0, iron_session_1.unsealData)(session.get('jwt'), {

@@ -6,2 +6,3 @@ "use strict";

const env_variables_js_1 = require("./env-variables.js");
const VERSION = '0.3.0';
const options = {

@@ -13,3 +14,3 @@ apiHostname: env_variables_js_1.WORKOS_API_HOSTNAME,

name: 'authkit-remix',
version: '0.2.0',
version: VERSION,
},

@@ -16,0 +17,0 @@ };

{
"name": "@workos-inc/authkit-remix",
"version": "0.2.0",
"version": "0.3.0",
"description": "Authentication and session helpers for using WorkOS & AuthKit with Remix",

@@ -29,3 +29,3 @@ "sideEffects": false,

"peerDependencies": {
"@remix-run/node": "^2.7.2",
"@remix-run/node": "^2.4.1",
"react": "^18.2.0"

@@ -39,2 +39,3 @@ },

"@typescript-eslint/eslint-plugin": "^6.7.4",
"prettier": "^3.3.3",
"typescript": "^5.4.2",

@@ -41,0 +42,0 @@ "typescript-eslint": "^7.2.0"

@@ -43,3 +43,3 @@ # AuthKit Remix Library

```sh
WORKOS_COOKIE_MAX_AGE='600' # maximum age of the cookie in seconds. Defaults to 31 days
WORKOS_COOKIE_MAX_AGE='600' # maximum age of the cookie in seconds. Defaults to 400 days
WORKOS_API_HOSTNAME='api.workos.com' # base WorkOS API URL

@@ -54,3 +54,3 @@ WORKOS_API_HTTPS=true # whether to use HTTPS in API calls

WorkOS requires that you have a callback URL to redirect users back to after they've authenticated. In your Remix app, [create a new route](https://remix.run/docs/en/main/discussion/routes) and add the following:
AuthKit requires that you have a callback URL to redirect users back to after they've authenticated. In your Remix app, [create a new route](https://remix.run/docs/en/main/discussion/routes) and add the following:

@@ -63,3 +63,3 @@ ```ts

Make sure this route matches the `WORKOS_REDIRECT_URI` variable and the configured redirect URI in your WorkOS dashboard. For instance if your redirect URI is `http://localhost:5173/callback` then you'd put the above code in `/app/routes/callback.ts`.
Make sure this route matches the `WORKOS_REDIRECT_URI` variable and the configured redirect URI in your WorkOS dashboard. For instance if your redirect URI is `http://localhost:2884/callback` then you'd put the above code in `/app/routes/callback.ts`.

@@ -74,21 +74,34 @@ You can also control the pathname the user will be sent to after signing-in by passing a `returnPathname` option to `authLoader` like so:

### Get the current user
### Access authentication data in your Remix application
For pages where you want to display a signed-in and signed-out view, use `withAuth` to retrieve the user profile from WorkOS.
Use `authkitLoader` to configure AuthKit for your Remix application routes.
```jsx
```tsx
import type { LoaderFunctionArgs } from '@remix-run/node';
import { authkitLoader } from '@workos-inc/authkit-remix';
export const loader = (args: LoaderFunctionArgs) => authkitLoader(args);
export function App() {
return (
<div>
<p>Welcome back {user?.firstName && `, ${user?.firstName}`}</p>
</div>
);
}
```
For pages where you want to display a signed-in and signed-out view, use `authkitLoader` to retrieve the user profile from WorkOS. You can pass in additional data by providing a loader function directly to `authkitLoader`.
```tsx
import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node';
import { Link, useLoaderData, json, Form } from '@remix-run/react';
import { getSignInUrl, getSignUpUrl, withAuth, signOut } from '@workos-inc/authkit-remix';
import { getSignInUrl, getSignUpUrl, signOut, authkitLoader } from '@workos-inc/authkit-remix';
export async function loader({request}: LoaderFunctionArgs) {
// additional properties include: sessionId, organizationId, role, impersonator, accessToken
const {user} = await withAuth(request);
export const loader = (args: LoaderFunctionArgs) => authkitLoader(args, async ({ request, auth }) => {
return json({
signInUrl: await getSignInUrl(),
signUpUrl: await getSignUpUrl(),
user,
signInUrl: await getSignInUrl();
signUpUrl: await getSignUpUrl();
});
}
});

@@ -101,2 +114,3 @@ export async function action({ request }: ActionFunctionArgs) {

// Retrieves the user from the session or returns `null` if no user is signed in
// Other supported values include sessionId, accessToken, organizationId, role, permissions and impersonator
const { user, signInUrl, signUpUrl } = useLoaderData<typeof loader>();

@@ -127,4 +141,4 @@

```jsx
const { user } = await withAuth(request, { ensureSignedIn: true });
```tsx
export const loader = (args: LoaderFunctionArgs) => authkitLoader(args, { ensureSignedIn: true });
```

@@ -142,23 +156,24 @@

```jsx
```tsx
import type { LoaderFunctionArgs, json } from '@remix-run/node';
import { withAuth } from '@workos-inc/authkit-remix';
export async function loader({ request }: LoaderFunctionArgs) {
const { accessToken } = await withAuth(request);
export const loader = (args: LoaderFunctionArgs) =>
authkitLoader(args, async ({ auth }) => {
const { accessToken } = auth;
if (!accesstoken) {
// Not signed in
}
if (!accessToken) {
// Not signed in
}
const serviceData = await fetch('/api/path', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const serviceData = await fetch('/api/path', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
return json({
data: serviceData,
return json({
data: serviceData,
});
});
}
```

@@ -168,18 +183,23 @@

To enable debug logs, pass in the debug flag when using `withAuth`.
To enable debug logs, pass in the debug flag when using `authkitLoader`.
```js
import { withAuth, getSignInUrl, getSignUpUrl } from '@workos-inc/authkit-remix';
```ts
import { authkitLoader } from '@workos-inc/authkit-remix';
export async function loader({ request }: LoaderFunctionArgs) {
const { user } = await withAuth(request, {
debug: true,
});
export const loader = (args: LoaderFunctionArgs) => authkitLoader(args, { debug: true });
```
return json({
signInUrl: await getSignInUrl(),
signUpUrl: await getSignUpUrl(),
user,
});
}
If providing a loader function, you can pass the options object as the third parameter
```ts
import { authkitLoader } from '@workos-inc/authkit-remix';
export const loader = (args: LoaderFunctionArgs) =>
authkitLoader(
args,
async ({ auth }) => {
return json({ foo: 'bar' });
},
{ debug: true },
);
```

@@ -16,13 +16,10 @@ import { HandleAuthOptions } from './interfaces.js';

const state = url.searchParams.get('state');
const returnPathname = state
? JSON.parse(atob(state)).returnPathname
: null;
const returnPathname = state ? JSON.parse(atob(state)).returnPathname : null;
if (code) {
try {
const { accessToken, refreshToken, user, impersonator } =
await workos.userManagement.authenticateWithCode({
clientId: WORKOS_CLIENT_ID,
code,
});
const { accessToken, refreshToken, user, impersonator } = await workos.userManagement.authenticateWithCode({
clientId: WORKOS_CLIENT_ID,
code,
});

@@ -43,2 +40,3 @@ // Clean up params

impersonator,
headers: {},
});

@@ -72,7 +70,6 @@

message: 'Something went wrong',
description:
'Couldn’t sign in. If you are not sure what happened, please contact your organization admin.',
description: 'Couldn’t sign in. If you are not sure what happened, please contact your organization admin.',
},
},
{ status: 500 }
{ status: 500 },
);

@@ -79,0 +76,0 @@ }

@@ -1,6 +0,2 @@

import {
WORKOS_REDIRECT_URI,
WORKOS_COOKIE_MAX_AGE,
WORKOS_COOKIE_PASSWORD,
} from './env-variables.js';
import { WORKOS_REDIRECT_URI, WORKOS_COOKIE_MAX_AGE, WORKOS_COOKIE_PASSWORD } from './env-variables.js';
import { createCookieSessionStorage } from '@remix-run/node';

@@ -20,15 +16,12 @@

// act as the actual time-limited aspects of the session.
maxAge: WORKOS_COOKIE_MAX_AGE
? parseInt(WORKOS_COOKIE_MAX_AGE, 10)
: 60 * 60 * 24 * 400,
maxAge: WORKOS_COOKIE_MAX_AGE ? parseInt(WORKOS_COOKIE_MAX_AGE, 10) : 60 * 60 * 24 * 400,
secrets: [WORKOS_COOKIE_PASSWORD],
};
const { getSession, commitSession, destroySession } =
createCookieSessionStorage({
cookie: {
name: cookieName,
...cookieOptions,
},
});
const { getSession, commitSession, destroySession } = createCookieSessionStorage({
cookie: {
name: cookieName,
...cookieOptions,
},
});
export { cookieName, getSession, commitSession, destroySession };

@@ -12,5 +12,3 @@ import { workos } from './workos.js';

redirectUri: WORKOS_REDIRECT_URI,
state: returnPathname
? btoa(JSON.stringify({ returnPathname }))
: undefined,
state: returnPathname ? btoa(JSON.stringify({ returnPathname })) : undefined,
screenHint,

@@ -17,0 +15,0 @@ });

import { authLoader } from './authkit-callback-route.js';
import { withAuth } from './session.js';
import { authkitLoader } from './session.js';
import { getSignInUrl, getSignUpUrl, signOut } from './auth.js';

@@ -12,3 +12,3 @@

//
withAuth,
authkitLoader,
};

@@ -11,2 +11,3 @@ import { User } from '@workos-inc/node';

}
export interface Session {

@@ -17,21 +18,5 @@ accessToken: string;

impersonator?: Impersonator;
headers: Record<string, string>;
}
export interface UserInfo {
user: User;
sessionId: string;
organizationId?: string;
role?: string;
permissions?: string[];
impersonator?: Impersonator;
accessToken: string;
}
export interface NoUserInfo {
user: null;
sessionId?: undefined;
organizationId?: undefined;
role?: undefined;
impersonator?: undefined;
}
export interface AccessToken {

@@ -49,10 +34,25 @@ sid: string;

export interface AuthkitMiddlewareAuth {
enabled: boolean;
unauthenticatedPaths: string[];
export interface AuthKitLoaderOptions {
ensureSignedIn?: boolean;
debug?: boolean;
}
export interface AuthkitMiddlewareOptions {
debug?: boolean;
middlewareAuth?: AuthkitMiddlewareAuth;
export interface AuthorizedData {
user: User;
sessionId: string;
accessToken: string;
organizationId: string | null;
role: string | null;
permissions: string[];
impersonator: Impersonator | null;
}
export interface UnauthorizedData {
user: null;
sessionId: null;
accessToken: null;
organizationId: null;
role: null;
permissions: null;
impersonator: null;
}

@@ -1,4 +0,5 @@

import { redirect } from '@remix-run/node';
import { json, redirect } from '@remix-run/node';
import type { LoaderFunctionArgs, SessionData, TypedResponse } from '@remix-run/node';
import { WORKOS_CLIENT_ID, WORKOS_COOKIE_PASSWORD } from './env-variables.js';
import { AccessToken, NoUserInfo, Session, UserInfo } from './interfaces.js';
import type { AccessToken, AuthorizedData, UnauthorizedData, AuthKitLoaderOptions, Session } from './interfaces.js';
import { getSession, destroySession, commitSession } from './cookie.js';

@@ -14,3 +15,3 @@ import { getAuthorizationUrl } from './get-authorization-url.js';

async function updateSession(request: Request, debug: boolean) {
const session = await getSessionFromCookie(request.headers.get('Cookie'));
const session = await getSessionFromCookie(request.headers.get('Cookie') as string);

@@ -45,2 +46,3 @@ // If no session, just continue

impersonator: session.impersonator,
headers: {},
};

@@ -51,4 +53,7 @@

updatedSession.set('jwt', await encryptSession(newSession));
await commitSession(updatedSession);
newSession.headers = {
'Set-Cookie': await commitSession(updatedSession),
};
return newSession;

@@ -72,19 +77,42 @@ } catch (e) {

async function withAuth(
request: Request,
options?: {
ensureSignedIn?: false;
debug?: boolean;
},
): Promise<UserInfo | NoUserInfo>;
type LoaderValue<Data> = Response | TypedResponse<Data> | NonNullable<Data> | null;
type LoaderReturnValue<Data> = Promise<LoaderValue<Data>> | LoaderValue<Data>;
async function withAuth(
request: Request,
options: {
ensureSignedIn?: true;
debug?: boolean;
},
): Promise<UserInfo>;
type AuthLoader<Data> = (
args: LoaderFunctionArgs & { auth: AuthorizedData | UnauthorizedData },
) => LoaderReturnValue<Data>;
async function withAuth(request: Request, { ensureSignedIn = false, debug = false } = {}) {
type AuthorizedAuthLoader<Data> = (args: LoaderFunctionArgs & { auth: AuthorizedData }) => LoaderReturnValue<Data>;
async function authkitLoader(
loaderArgs: LoaderFunctionArgs,
options: AuthKitLoaderOptions & { ensureSignedIn: true },
): Promise<TypedResponse<AuthorizedData>>;
async function authkitLoader(
loaderArgs: LoaderFunctionArgs,
options?: AuthKitLoaderOptions,
): Promise<TypedResponse<AuthorizedData | UnauthorizedData>>;
async function authkitLoader<Data = unknown>(
loaderArgs: LoaderFunctionArgs,
loader: AuthorizedAuthLoader<Data>,
options: AuthKitLoaderOptions & { ensureSignedIn: true },
): Promise<TypedResponse<Data & AuthorizedData>>;
async function authkitLoader<Data = unknown>(
loaderArgs: LoaderFunctionArgs,
loader: AuthLoader<Data>,
options?: AuthKitLoaderOptions,
): Promise<TypedResponse<Data & (AuthorizedData | UnauthorizedData)>>;
async function authkitLoader<Data = unknown>(
loaderArgs: LoaderFunctionArgs,
loaderOrOptions?: AuthLoader<Data> | AuthorizedAuthLoader<Data> | AuthKitLoaderOptions,
options: AuthKitLoaderOptions = {},
) {
const loader = typeof loaderOrOptions === 'function' ? loaderOrOptions : undefined;
const { ensureSignedIn = false, debug = false } = typeof loaderOrOptions === 'object' ? loaderOrOptions : options;
const { request } = loaderArgs;
const session = await updateSession(request, debug);

@@ -103,25 +131,84 @@

}
return { user: null };
const auth: UnauthorizedData = {
user: null,
accessToken: null,
impersonator: null,
organizationId: null,
permissions: null,
role: null,
sessionId: null,
};
return await handleAuthLoader(loader, loaderArgs, auth);
}
const { sid: sessionId, org_id: organizationId, role, permissions } = decodeJwt<AccessToken>(session.accessToken);
const {
sessionId,
organizationId = null,
role = null,
permissions = [],
} = getClaimsFromAccessToken(session.accessToken);
return {
const auth: AuthorizedData = {
user: session.user,
sessionId,
user: session.user,
accessToken: session.accessToken,
organizationId,
role,
permissions,
impersonator: session.impersonator,
accessToken: session.accessToken,
impersonator: session.impersonator ?? null,
};
return await handleAuthLoader(loader, loaderArgs, auth, session);
}
async function handleAuthLoader(
loader: AuthLoader<unknown> | AuthorizedAuthLoader<unknown> | undefined,
args: LoaderFunctionArgs,
auth: AuthorizedData | UnauthorizedData,
session?: Session,
) {
if (!loader) {
return json(auth, session ? { headers: { ...session.headers } } : undefined);
}
// If there's a custom loader, get the resulting data and return it with our
// auth data plus session cookie header
const loaderResult = await loader({ ...args, auth: auth as AuthorizedData });
if (loaderResult instanceof Response) {
// If the result is a redirect, return it unedited
if (loaderResult.status >= 300 && loaderResult.status < 400) {
return loaderResult;
}
const newResponse = new Response(loaderResult.body, loaderResult);
const data = await newResponse.json();
// Set the content type in case the user returned a Response instead of the
// json helper method
newResponse.headers.set('Content-Type', 'application/json; charset=utf-8');
if (session) {
newResponse.headers.append('Set-Cookie', session.headers['Set-Cookie']);
}
return json({ ...data, ...auth }, newResponse);
}
// If the loader returns a non-Response, assume it's a data object
return json({ ...loaderResult, ...auth }, session ? { headers: { ...session.headers } } : undefined);
}
async function terminateSession(request: Request) {
const { sessionId } = await withAuth(request);
const encryptedSession = await getSession(request.headers.get('Cookie'));
const { accessToken } = (await getSessionFromCookie(
request.headers.get('Cookie') as string,
encryptedSession,
)) as Session;
const cookieSession = await getSession(request.headers.get('Cookie'));
const { sessionId } = getClaimsFromAccessToken(accessToken);
const headers = {
'Set-Cookie': await destroySession(cookieSession),
'Set-Cookie': await destroySession(encryptedSession),
};

@@ -134,2 +221,3 @@

}
return redirect('/', {

@@ -140,5 +228,18 @@ headers,

async function getSessionFromCookie(cookie: string | null) {
const session = await getSession(cookie);
function getClaimsFromAccessToken(accessToken: string) {
const { sid: sessionId, org_id: organizationId, role, permissions } = decodeJwt<AccessToken>(accessToken);
return {
sessionId,
organizationId,
role,
permissions,
};
}
async function getSessionFromCookie(cookie: string, session?: SessionData) {
if (!session) {
session = await getSession(cookie);
}
if (session.has('jwt')) {

@@ -162,2 +263,2 @@ return unsealData<Session>(session.get('jwt'), {

export { encryptSession, withAuth, terminateSession };
export { encryptSession, terminateSession, authkitLoader };
import { WorkOS } from '@workos-inc/node';
import { WORKOS_API_HOSTNAME, WORKOS_API_HTTPS, WORKOS_API_KEY, WORKOS_API_PORT } from './env-variables.js';
const VERSION = '0.3.0';
const options = {

@@ -10,3 +12,3 @@ apiHostname: WORKOS_API_HOSTNAME,

name: 'authkit-remix',
version: '0.2.0',
version: VERSION,
},

@@ -13,0 +15,0 @@ };

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc