New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@a-type/auth

Package Overview
Dependencies
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@a-type/auth - npm Package Compare versions

Comparing version 0.4.0 to 0.4.1

61

dist/esm/handlers.js

@@ -12,2 +12,13 @@ import { AuthError } from './error.js';

}
function toRedirect(destination, session) {
// add search params to destination
const url = new URL(destination);
for (const [key, value] of session.searchParams) {
url.searchParams.append(key, value);
}
return new Response(null, {
status: 302,
headers: Object.assign({ location: url.toString() }, session.headers),
});
}
function handleOAuthLoginRequest(req, opts) {

@@ -31,3 +42,3 @@ var _a;

async function handleOAuthCallbackRequest(req, opts) {
var _a, _b, _c, _d, _e, _f;
var _a, _b, _c, _d;
const url = new URL(req.url);

@@ -80,11 +91,6 @@ const code = url.searchParams.get('code');

const session = await sessions.createSession(userId);
const clientDomain = (_e = (_d = req.headers.get('origin')) !== null && _d !== void 0 ? _d : req.headers.get('host')) !== null && _e !== void 0 ? _e : undefined;
const { headers: sessionHeaders } = await sessions.updateSession(session, {
const sessionUpdate = await sessions.updateSession(session, {
sendRefreshToken: true,
clientDomain,
});
return new Response(null, {
status: 302,
headers: Object.assign(Object.assign({}, sessionHeaders), { location: (_f = url.searchParams.get('returnTo')) !== null && _f !== void 0 ? _f : defaultReturnTo }),
});
return toRedirect((_d = url.searchParams.get('returnTo')) !== null && _d !== void 0 ? _d : defaultReturnTo, sessionUpdate);
}

@@ -95,5 +101,6 @@ async function handleLogoutRequest(req) {

const returnTo = (_a = url.searchParams.get('returnTo')) !== null && _a !== void 0 ? _a : defaultReturnTo;
const { headers } = sessions.clearSession();
return new Response(null, {
status: 302,
headers: Object.assign(Object.assign({}, sessions.clearSession()), { location: returnTo }),
headers: Object.assign(Object.assign({}, headers), { location: returnTo }),
});

@@ -136,3 +143,3 @@ }

async function handleVerifyEmailRequest(req) {
var _a, _b, _c, _d, _e;
var _a, _b, _c;
const url = new URL(req.url);

@@ -181,14 +188,9 @@ const code = url.searchParams.get('code');

const session = await sessions.createSession(userId);
const clientDomain = (_d = (_c = req.headers.get('origin')) !== null && _c !== void 0 ? _c : req.headers.get('host')) !== null && _d !== void 0 ? _d : undefined;
const { headers } = await sessions.updateSession(session, {
const sessionUpdate = await sessions.updateSession(session, {
sendRefreshToken: true,
clientDomain,
});
return new Response(null, {
status: 302,
headers: Object.assign(Object.assign({}, headers), { location: (_e = url.searchParams.get('returnTo')) !== null && _e !== void 0 ? _e : defaultReturnTo }),
});
return toRedirect((_c = url.searchParams.get('returnTo')) !== null && _c !== void 0 ? _c : defaultReturnTo, sessionUpdate);
}
async function handleEmailLoginRequest(req) {
var _a, _b, _c, _d;
var _a, _b;
const formData = await req.formData();

@@ -210,11 +212,6 @@ const email = formData.get('email');

const session = await sessions.createSession(user.id);
const clientDomain = (_c = (_b = req.headers.get('origin')) !== null && _b !== void 0 ? _b : req.headers.get('host')) !== null && _c !== void 0 ? _c : undefined;
const { headers } = await sessions.updateSession(session, {
const sessionUpdate = await sessions.updateSession(session, {
sendRefreshToken: true,
clientDomain,
});
return new Response(null, {
status: 302,
headers: Object.assign(Object.assign({}, headers), { location: (_d = params.returnTo) !== null && _d !== void 0 ? _d : defaultReturnTo }),
});
return toRedirect((_b = params.returnTo) !== null && _b !== void 0 ? _b : defaultReturnTo, sessionUpdate);
}

@@ -248,3 +245,3 @@ async function handleResetPasswordRequest(req) {

async function handleVerifyPasswordResetRequest(req) {
var _a, _b, _c, _d;
var _a, _b;
const url = new URL(req.url);

@@ -268,11 +265,6 @@ const code = url.searchParams.get('code');

const session = await sessions.createSession(user.id);
const clientDomain = (_c = (_b = req.headers.get('origin')) !== null && _b !== void 0 ? _b : req.headers.get('host')) !== null && _c !== void 0 ? _c : undefined;
const { headers } = await sessions.updateSession(session, {
const sessionUpdate = await sessions.updateSession(session, {
sendRefreshToken: true,
clientDomain,
});
return new Response(null, {
status: 302,
headers: Object.assign(Object.assign({}, headers), { location: (_d = url.searchParams.get('returnTo')) !== null && _d !== void 0 ? _d : defaultReturnTo }),
});
return toRedirect((_b = url.searchParams.get('returnTo')) !== null && _b !== void 0 ? _b : defaultReturnTo, sessionUpdate);
}

@@ -303,5 +295,6 @@ async function handleSessionRequest(req) {

}
const { headers } = await sessions.refreshSession(accessToken, refreshToken);
const { headers, searchParams } = await sessions.refreshSession(accessToken, refreshToken);
return new Response(JSON.stringify({
ok: true,
refreshToken: searchParams.get('refreshToken'),
}), {

@@ -308,0 +301,0 @@ status: 200,

@@ -82,3 +82,3 @@ import { parse, serialize } from 'cookie';

};
this.updateSession = async (session, { sendRefreshToken, clientDomain = this.options.audience, } = { sendRefreshToken: false }) => {
this.updateSession = async (session, { sendRefreshToken, } = { sendRefreshToken: false }) => {
const jti = randomUUID();

@@ -95,19 +95,11 @@ const accessTokenBuilder = this.getAccessTokenBuilder(session, jti);

};
const searchParams = new URLSearchParams();
if (sendRefreshToken) {
const refreshTokenBuilder = this.getRefreshTokenBuilder(jti);
const refreshToken = await refreshTokenBuilder.sign(this.secret);
// construct a short lived cookie for the client domain
// which is client accessible. this lets us pass the refresh token
// to the client so it can store it itself, even if the response
// is a document.
const refreshCookie = serialize(this.refreshCookieName, refreshToken, {
httpOnly: false,
sameSite: 'strict',
path: '/',
domain: clientDomain,
});
headers['Set-Cookie'] += '; ' + refreshCookie;
searchParams.set(this.refreshParam, refreshToken);
}
return {
headers,
searchParams,
};

@@ -117,3 +109,5 @@ };

return {
'Set-Cookie': `${this.options.cookieName}=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0`,
headers: {
'Set-Cookie': `${this.options.cookieName}=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0`,
},
};

@@ -172,7 +166,7 @@ };

}
get refreshCookieName() {
get refreshParam() {
var _a;
return ((_a = this.options.refreshCookieName) !== null && _a !== void 0 ? _a : `${this.options.cookieName}-refresh`);
return (_a = this.options.refreshParam) !== null && _a !== void 0 ? _a : `refreshToken`;
}
}
//# sourceMappingURL=session.js.map

@@ -20,22 +20,4 @@ import { it, describe, vi, beforeAll, expect } from 'vitest';

});
it('should send a refresh token in a cookie for the client domain', async () => {
const { headers } = await sessions.updateSession({ userId: '123' }, {
sendRefreshToken: true,
clientDomain: 'client.com',
});
const cookies = parse(headers['Set-Cookie']);
const authToken = cookies['session'];
const refreshToken = cookies['session-refresh'];
expect(authToken).toBeTruthy();
expect(refreshToken).toBeTruthy();
// cookie should be for the client domain
expect(headers['Set-Cookie']).toMatch(/session-refresh=(.*);\s+Domain=client.com;\s+Path=\/;/);
// without specifying client domain, it defaults to audience
const { headers: headers2 } = await sessions.updateSession({ userId: '123' }, {
sendRefreshToken: true,
});
expect(headers2['Set-Cookie']).toMatch(/session-refresh=(.*);\s+Domain=example.com;\s+Path=\/;/);
});
it('should refresh an expired JWT', async () => {
const { headers } = await sessions.updateSession({ userId: '123' }, {
const { headers, searchParams } = await sessions.updateSession({ userId: '123' }, {
sendRefreshToken: true,

@@ -45,3 +27,3 @@ });

const authToken = cookies['session'];
const refreshToken = cookies['session-refresh'];
const refreshToken = searchParams.get('refreshToken');
// verify that the token is accepted

@@ -66,6 +48,6 @@ let req = {

// verify that the refresh token is accepted
const { headers: newSessionHeaders } = await sessions.refreshSession(authToken, refreshToken);
const { headers: newSessionHeaders, searchParams: newSessionSearchParams } = await sessions.refreshSession(authToken, refreshToken);
const newCookies = parse(newSessionHeaders['Set-Cookie']);
const newAuthToken = newCookies['session'];
const newRefreshToken = newCookies['session-refresh'];
const newRefreshToken = newSessionSearchParams.get('refreshToken');
// verify that the new token is accepted

@@ -84,3 +66,3 @@ req = {

it('should not allow refreshing any old token', async () => {
const { headers } = await sessions.updateSession({ userId: '123' }, {
const { headers, searchParams } = await sessions.updateSession({ userId: '123' }, {
sendRefreshToken: true,

@@ -98,3 +80,3 @@ });

const jti = verifiedAuth.payload.jti;
const refreshToken = cookies['session-refresh'];
const refreshToken = searchParams.get('refreshToken');
// sign a JWT with some other signature

@@ -101,0 +83,0 @@ const badToken = await new SignJWT({})

@@ -17,3 +17,3 @@ export interface Session {

cookieName: string;
refreshCookieName?: string;
refreshParam?: string;
shortNames: ShortNames;

@@ -44,10 +44,15 @@ mode?: 'production' | 'development';

headers: Record<string, string>;
searchParams: URLSearchParams;
}>;
updateSession: (session: Session, { sendRefreshToken, clientDomain, }?: {
updateSession: (session: Session, { sendRefreshToken, }?: {
sendRefreshToken?: boolean | undefined;
clientDomain?: string | undefined;
}) => Promise<{
headers: Record<string, string>;
searchParams: URLSearchParams;
}>;
clearSession: () => Record<string, string>;
clearSession: () => {
headers: {
'Set-Cookie': string;
};
};
private getAccessTokenBuilder;

@@ -58,3 +63,3 @@ private getRefreshTokenBuilder;

private readSessionFromPayload;
private get refreshCookieName();
private get refreshParam();
}
{
"name": "@a-type/auth",
"version": "0.4.0",
"version": "0.4.1",
"description": "My personal auth request handlers",

@@ -5,0 +5,0 @@ "module": "dist/esm/index.js",

@@ -35,2 +35,20 @@ import { AuthDB } from './db.js';

function toRedirect(
destination: string,
session: { headers: Record<string, string>; searchParams: URLSearchParams },
) {
// add search params to destination
const url = new URL(destination);
for (const [key, value] of session.searchParams) {
url.searchParams.append(key, value);
}
return new Response(null, {
status: 302,
headers: {
location: url.toString(),
...session.headers,
},
});
}
function handleOAuthLoginRequest(req: Request, opts: { provider: string }) {

@@ -114,15 +132,9 @@ const url = new URL(req.url);

const session = await sessions.createSession(userId);
const clientDomain =
req.headers.get('origin') ?? req.headers.get('host') ?? undefined;
const { headers: sessionHeaders } = await sessions.updateSession(session, {
const sessionUpdate = await sessions.updateSession(session, {
sendRefreshToken: true,
clientDomain,
});
return new Response(null, {
status: 302,
headers: {
...sessionHeaders,
location: url.searchParams.get('returnTo') ?? defaultReturnTo,
},
});
return toRedirect(
url.searchParams.get('returnTo') ?? defaultReturnTo,
sessionUpdate,
);
}

@@ -133,6 +145,7 @@

const returnTo = url.searchParams.get('returnTo') ?? defaultReturnTo;
const { headers } = sessions.clearSession();
return new Response(null, {
status: 302,
headers: {
...sessions.clearSession(),
...headers,
location: returnTo,

@@ -225,15 +238,9 @@ },

const session = await sessions.createSession(userId);
const clientDomain =
req.headers.get('origin') ?? req.headers.get('host') ?? undefined;
const { headers } = await sessions.updateSession(session, {
const sessionUpdate = await sessions.updateSession(session, {
sendRefreshToken: true,
clientDomain,
});
return new Response(null, {
status: 302,
headers: {
...headers,
location: url.searchParams.get('returnTo') ?? defaultReturnTo,
},
});
return toRedirect(
url.searchParams.get('returnTo') ?? defaultReturnTo,
sessionUpdate,
);
}

@@ -264,15 +271,6 @@

const session = await sessions.createSession(user.id);
const clientDomain =
req.headers.get('origin') ?? req.headers.get('host') ?? undefined;
const { headers } = await sessions.updateSession(session, {
const sessionUpdate = await sessions.updateSession(session, {
sendRefreshToken: true,
clientDomain,
});
return new Response(null, {
status: 302,
headers: {
...headers,
location: params.returnTo ?? defaultReturnTo,
},
});
return toRedirect(params.returnTo ?? defaultReturnTo, sessionUpdate);
}

@@ -328,15 +326,9 @@

const session = await sessions.createSession(user.id);
const clientDomain =
req.headers.get('origin') ?? req.headers.get('host') ?? undefined;
const { headers } = await sessions.updateSession(session, {
const sessionUpdate = await sessions.updateSession(session, {
sendRefreshToken: true,
clientDomain,
});
return new Response(null, {
status: 302,
headers: {
...headers,
location: url.searchParams.get('returnTo') ?? defaultReturnTo,
},
});
return toRedirect(
url.searchParams.get('returnTo') ?? defaultReturnTo,
sessionUpdate,
);
}

@@ -374,3 +366,3 @@

const { headers } = await sessions.refreshSession(
const { headers, searchParams } = await sessions.refreshSession(
accessToken,

@@ -383,2 +375,3 @@ refreshToken,

ok: true,
refreshToken: searchParams.get('refreshToken'),
}),

@@ -385,0 +378,0 @@ {

@@ -23,38 +23,4 @@ import { it, describe, vi, beforeAll, expect } from 'vitest';

it('should send a refresh token in a cookie for the client domain', async () => {
const { headers } = await sessions.updateSession(
{ userId: '123' },
{
sendRefreshToken: true,
clientDomain: 'client.com',
},
);
const cookies = parse(headers['Set-Cookie']);
const authToken = cookies['session'];
const refreshToken = cookies['session-refresh'];
expect(authToken).toBeTruthy();
expect(refreshToken).toBeTruthy();
// cookie should be for the client domain
expect(headers['Set-Cookie']).toMatch(
/session-refresh=(.*);\s+Domain=client.com;\s+Path=\/;/,
);
// without specifying client domain, it defaults to audience
const { headers: headers2 } = await sessions.updateSession(
{ userId: '123' },
{
sendRefreshToken: true,
},
);
expect(headers2['Set-Cookie']).toMatch(
/session-refresh=(.*);\s+Domain=example.com;\s+Path=\/;/,
);
});
it('should refresh an expired JWT', async () => {
const { headers } = await sessions.updateSession(
const { headers, searchParams } = await sessions.updateSession(
{ userId: '123' },

@@ -68,3 +34,3 @@ {

const authToken = cookies['session'];
const refreshToken = cookies['session-refresh'];
const refreshToken = searchParams.get('refreshToken')!;

@@ -95,10 +61,8 @@ // verify that the token is accepted

// verify that the refresh token is accepted
const { headers: newSessionHeaders } = await sessions.refreshSession(
authToken,
refreshToken,
);
const { headers: newSessionHeaders, searchParams: newSessionSearchParams } =
await sessions.refreshSession(authToken, refreshToken);
const newCookies = parse(newSessionHeaders['Set-Cookie']);
const newAuthToken = newCookies['session'];
const newRefreshToken = newCookies['session-refresh'];
const newRefreshToken = newSessionSearchParams.get('refreshToken')!;

@@ -121,3 +85,3 @@ // verify that the new token is accepted

it('should not allow refreshing any old token', async () => {
const { headers } = await sessions.updateSession(
const { headers, searchParams } = await sessions.updateSession(
{ userId: '123' },

@@ -143,3 +107,3 @@ {

const jti = verifiedAuth.payload.jti!;
const refreshToken = cookies['session-refresh'];
const refreshToken = searchParams.get('refreshToken')!;

@@ -146,0 +110,0 @@ // sign a JWT with some other signature

@@ -33,3 +33,3 @@ import { parse, serialize } from 'cookie';

cookieName: string;
refreshCookieName?: string;
refreshParam?: string;
shortNames: ShortNames;

@@ -116,8 +116,3 @@ mode?: 'production' | 'development';

*/
refreshSession = async (
accessToken: string,
refreshToken: string,
): Promise<{
headers: Record<string, string>;
}> => {
refreshSession = async (accessToken: string, refreshToken: string) => {
const refreshData = await jwtVerify(refreshToken, this.secret, {

@@ -146,10 +141,6 @@ issuer: this.options.issuer,

sendRefreshToken,
clientDomain = this.options.audience,
}: {
sendRefreshToken?: boolean;
clientDomain?: string;
} = { sendRefreshToken: false },
): Promise<{
headers: Record<string, string>;
}> => {
) => {
const jti = randomUUID();

@@ -167,2 +158,3 @@ const accessTokenBuilder = this.getAccessTokenBuilder(session, jti);

};
const searchParams = new URLSearchParams();

@@ -172,13 +164,3 @@ if (sendRefreshToken) {

const refreshToken = await refreshTokenBuilder.sign(this.secret);
// construct a short lived cookie for the client domain
// which is client accessible. this lets us pass the refresh token
// to the client so it can store it itself, even if the response
// is a document.
const refreshCookie = serialize(this.refreshCookieName, refreshToken, {
httpOnly: false,
sameSite: 'strict',
path: '/',
domain: clientDomain,
});
headers['Set-Cookie'] += '; ' + refreshCookie;
searchParams.set(this.refreshParam, refreshToken);
}

@@ -188,8 +170,11 @@

headers,
searchParams,
};
};
clearSession = (): Record<string, string> => {
clearSession = () => {
return {
'Set-Cookie': `${this.options.cookieName}=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0`,
headers: {
'Set-Cookie': `${this.options.cookieName}=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0`,
},
};

@@ -253,7 +238,5 @@ };

private get refreshCookieName() {
return (
this.options.refreshCookieName ?? `${this.options.cookieName}-refresh`
);
private get refreshParam() {
return this.options.refreshParam ?? `refreshToken`;
}
}

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