class

NextjsAuthTagger

Inherits FrameworkTagger < FileHelper < Tagger < Reference < Object

Constants

BODY_READ = /\.\s*(?:json|formData|text)\s*\(|\breq(?:uest)?\s*\.\s*body\b/

A read of the submitted body. With a password in it, the helper is a login.

BRANCH_ANSWER = /\breturn\b|\bres\s*\.\s*(?:status|json|send|end|redirect)\b/
BRANCH_HEAD = /\b(?:if|switch)\s*\(/
CALLER_CHECK = /\b([A-Za-z_$][\w$]*)\s*=\s*(?:await\s+)?([\w$.]*(?:[Aa]uth|[Ss]ession)\w*)\s*\(\s*(?:\)|req(?:uest)?\b|headers\(\)|cookies\(\))/

auth = await checkAuth(request), const session = await getSession(): group 1 the value, group 2 the callee. Whether the callee checks the caller is judged by its definition (caller_check_callee?).

CARRIER = /\A\s*(?:(?:let|const|var)\s+)?([A-Za-z_$][\w$]*)\s*=(?![=>])/

error = () => unauthorized();: group 1 the name a refusal is stored in.

CONDITION_LOOKBACK = 6

How far above the 401 its if may sit (a Prettier-wrapped reply).

CONTROL_WORDS = Set {"if", "for", "while", "switch", "catch", "function"}
COOKIE_WRITE = /\bcookies\s*\(\s*\)\s*\.\s*set\s*\(|\.\s*cookies\s*\.\s*set\s*\(|set-cookie/i

Starting a session (cookies().set(...), a Set-Cookie header) is a login too.

CREDENTIAL = /password|credential/i
DESTRUCTURED_RESULT = /^\s*(?:const|let|var)\s+\{([^}]*)\}\s*=/

const { auth, error } = await parseRequest(request);

ELSE_BRANCH = /\A\}?\s*else\b/

} else if (…) {, else {: a sibling branch of the if above it.

ENV_GATE = /\Aif\s*\(\s*!?\s*process\.env\.\w+(?:\s*[!=]==?\s*['"`][^'"`]*['"`])?\s*\)\s*(?:\{\z|return\b)/

if (process.env.CLOUD_MODE) { / if (process.env.X !== '1') return notFound();: a deployment switch. One that refuses everyone may come before the check; any other runs for a caller the check would refuse, when set.

ENV_REFUSAL = /\b(?:return|throw)\b[\s\S]*(?:\bstatus(?:Code)?\s*(?::|\()\s*4\d\d\b|\b(?:notFound|forbidden|unauthorized|badRequest|methodNotAllowed)\s*\()/
ENV_SECRET = /process\.env\.(?!NEXT_PUBLIC_)(?!\w*PUBLISHABLE)\w*(?:KEY|SECRET|TOKEN)\w*/

A server-side secret: not one the browser is given (NEXT_PUBLIC_*, Stripe's *_PUBLISHABLE_KEY).

HELPER_STATEMENT = /^\s*(?:return\s+|(?:const|let|var)\s+[^=]+=\s*)?(?:await\s+)?([A-Za-z_$][\w$]*)\s*\(/

A statement of the handler that starts with a call: const user = await authMiddleware();, validateRequest(request);, return await handler(request);. Group 1 is the callee.

MAX_HELPER_DEPTH = 2

How many helper hops to follow (GET → handler → checkCronKey).

METHOD_ALIAS = /\b(?:const|let|var)\s+(?:([A-Za-z_$][\w$]*)\s*=\s*req(?:uest)?\.method\b|\{[^}]*\bmethod\b[^}]*\}\s*=\s*req(?:uest)?\s*;?\s*\z)/

const method = req.method, const isGet = request.method === 'GET', const { method } = req: names the verb is read into.

NEGATED_LIST = /\bif\s*\(.*!\s*\[/

if (![process.env.CRON_API_KEY, Bearer ${process.env.CRON_SECRET}] .includes(apiKey)): the key is none of the accepted secrets. Read on the line as written, since the template literal holds a secret.

NEGATED_VALUE = /\bif\s*\(\s*!\s*([A-Za-z_$][\w$]*)(?:\s*\??\.\s*[A-Za-z_$][\w$]*)*\s*\)/

if (!auth): group 1 the value whose absence is refused.

OPTION_NOTE = "an option can make it public"
REPLY_CALL = /(?:\breturn\s+|\bthrow\s+|=>\s*)(?:await\s+)?([A-Za-z_$][\w$]*)\s*\(/

return unauthorized(), throw unauthorized(), error = () => forbidden(): a call whose own definition replies 401/403 is that reply. Group 1 the callee.

RESULT_NAME = /^\s*(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=/

const denied = await checkAuth(); if (denied) return denied;

SCHEMA_FACTORY_CALL = /\A\s*(?:const|let|var)\s+[A-Za-z_$][\w$]*\s*=\s*([A-Za-z_$][\w$]*)\s*\(/
SCHEMA_RETURN = /\breturn\s+(?:z|yup|Joi)\b/
SECRET_LIST = /!\s*\[([^\]]*)\]\s*\.\s*includes\s*\(/
SECRET_TEMPLATE = /!==?\s*`[^`]*\$\{\s*#{ENV_SECRET}\s*\}[^`]*`|`[^`]*\$\{\s*#{ENV_SECRET}\s*\}[^`]*`\s*!==?/

if (authHeader !== `Bearer ${process.env.CRON_SECRET}`): also read as written, the secret being inside a template literal.

SESSION_DENIED = /\bif\s*\(.*(?:!\s*session\b|\bsession\s*(?:\?\.\w+\s*)*(?:===?|!==?)\s*(?:null|undefined)\b|#{ENV_SECRET}\s*!==?|!==?\s*#{ENV_SECRET})/
SETTING_NOTE = "a setting can open it"
THROWN_UNAUTHORIZED = /\bthrow\b[\s\S]{0,240}unauthori[sz]ed/i

throw new DubApiError({ code: "unauthorized" }): the word lives in a string, so this is matched on text that still has strings. The { sits between throw and the word, and the object may wrap a line or two.

UNAUTHORIZED = /\bstatus(?:Code)?\s*(?::|\()\s*(40[13])\b/

Next.js has no route-level guard syntax: an API route checks the caller in its own body (if (!session) return NextResponse.json(.., { status: 401 })). A 401 reply under a condition on the session, or on a value compared with a process.env secret, is that check. A 401 under any other condition (if (!user) after a password lookup) is a login failure anonymous callers are meant to reach, so it does not count. 401, or 403 ({ status: 403 } for a wrong cron key): both refuse the caller, and SESSION_DENIED decides whether the condition is about them.

VERB_READ = /\breq(?:uest)?\.method\b/

A pages-router handler serves every verb from one body; a 401 after a branch on req.method that answers some verbs guards only the others. A branch that just refuses other verbs with 405 leaves one verb, and one that answers nothing (else if (isGet) { query = … }) splits no verbs.

VERB_WRAPPER = /\b(?:GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s*=\s*([A-Za-z_$][\w$]*)\s*\(/

export const GET = withSession(async ...). The wrapper is the guard.

WRAPPED_HANDLER = /\b(?:GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s*=\s*[A-Za-z_$][\w$]*\s*\(\s*([A-Za-z_$][\w$]*)\s*\)/

export const GET = defaultResponderForAppDir(handler): group 1 the handler the wrapper is handed.

Class methods

target_techs
Source

Nested types