next-firebase-auth-edge
Version:
Next.js Firebase Authentication for Edge and server runtimes. Compatible with latest Next.js features.
85 lines (84 loc) • 2.98 kB
JavaScript
import { decodeJwt } from 'jose';
import { isInvalidTokenError } from '../auth/error.js';
import { mapJwtPayloadToDecodedIdToken } from '../auth/utils.js';
import { debug, enableDebugMode } from '../debug/index.js';
import { CookieParserFactory } from './cookies/parser/CookieParserFactory.js';
export function validateOptions(options) {
if (!options.cookieSignatureKeys.length || !options.cookieSignatureKeys[0]) {
throw new Error(`Expected cookieSignatureKeys to contain at least one signature key. Received: ${JSON.stringify(options.cookieSignatureKeys)}`);
}
}
export function getRequestCookiesTokens(cookies, options) {
const parser = CookieParserFactory.fromRequestCookies(cookies, options);
return parser.parseCookies();
}
export async function getTokens(cookies, options) {
const now = Date.now();
if (options.debug) {
enableDebugMode();
}
validateOptions(options);
try {
const tokens = await getRequestCookiesTokens(cookies, options);
debug('getTokens: Tokens successfully extracted from cookies');
const payload = decodeJwt(tokens.idToken);
return {
token: tokens.idToken,
decodedToken: mapJwtPayloadToDecodedIdToken(payload),
customToken: tokens.customToken,
metadata: tokens.metadata
};
}
catch (error) {
if (isInvalidTokenError(error)) {
debug(`Token is missing or has incorrect formatting. This is expected and usually means that user has not yet logged in`, {
reason: error.reason
});
return null;
}
throw error;
}
finally {
debug(`getTokens: took ${(Date.now() - now) / 1000}ms`);
}
}
export function getCookiesTokens(cookies, options) {
const parser = CookieParserFactory.fromObject(cookies, options);
return parser.parseCookies();
}
export async function getApiRequestTokens(request, options) {
try {
const tokens = await getCookiesTokens(request.cookies, options);
const payload = decodeJwt(tokens.idToken);
return {
token: tokens.idToken,
decodedToken: mapJwtPayloadToDecodedIdToken(payload),
customToken: tokens.customToken,
metadata: tokens.metadata
};
}
catch (error) {
if (isInvalidTokenError(error)) {
return null;
}
throw error;
}
}
export async function getTokensFromObject(cookies, options) {
try {
const tokens = await getCookiesTokens(cookies, options);
const payload = decodeJwt(tokens.idToken);
return {
token: tokens.idToken,
decodedToken: mapJwtPayloadToDecodedIdToken(payload),
customToken: tokens.customToken,
metadata: tokens.metadata
};
}
catch (error) {
if (isInvalidTokenError(error)) {
return null;
}
throw error;
}
}