add ms to access token to randomize it

master
Peter Babič 5 years ago
parent 316d8c524f
commit 28666f00f9
Signed by: peter.babic
GPG Key ID: 4BB075BC1884BA40
  1. 1
      src/server/UserResolver.spec.ts
  2. 86
      src/server/userResolver/auth.ts

@ -60,6 +60,7 @@ describe("resolver of user", () => {
expect(jwtLifetime).toBeGreaterThanOrEqual(oneMinute)
expect(jwtLifetime).not.toBeGreaterThan(sixteenMinutes)
expect(jwtPayload.userId).toBe(user.id)
expect(jwtPayload.ms).toBeLessThan(1000)
expect(response.errors).toBeUndefined()
})
)

@ -4,84 +4,86 @@ import { sign as jwtSign, verify as jwtVerify } from "jsonwebtoken"
import { AuthChecker } from "type-graphql"
export const hashPassword = async (password: string) =>
await argonHash(password, { type: argon2id })
await argonHash(password, { type: argon2id })
export const comparePasswords = async (hash: string, plain: string) => {
if (!(await argonVerify(hash, plain, { type: argon2id }))) {
throw new Error("Passwords do not match")
}
if (!(await argonVerify(hash, plain, { type: argon2id }))) {
throw new Error("Passwords do not match")
}
return true
return true
}
export const signAccessToken = (payload: ContextPayload) => {
const accessTokenSecret = process.env.ACCESS_SECRET as string
const accessTokenSecret = process.env.ACCESS_SECRET as string
const payloadWithMs = { ...payload, ms: Date.now() % 1000 }
return jwtSign(payload, accessTokenSecret, {
expiresIn: parseInt(process.env.ACCESS_EXPIRY as string),
})
return jwtSign(payloadWithMs, accessTokenSecret, {
expiresIn: parseInt(process.env.ACCESS_EXPIRY as string),
})
}
export const signRefreshToken = (payload: ContextPayload) => {
const accessTokenSecret = process.env.REFRESH_SECRET as string
const accessTokenSecret = process.env.REFRESH_SECRET as string
return jwtSign(payload, accessTokenSecret, {
expiresIn: parseInt(process.env.REFRESH_EXPIRY as string),
})
return jwtSign(payload, accessTokenSecret, {
expiresIn: parseInt(process.env.REFRESH_EXPIRY as string),
})
}
export const verifiedAccessTokenPayload = (token: string) => {
const accessTokenSecret = process.env.ACCESS_SECRET as string
const accessTokenSecret = process.env.ACCESS_SECRET as string
return jwtVerify(token, accessTokenSecret) as JWTPayload
return jwtVerify(token, accessTokenSecret) as JWTPayload
}
export const verifiedRefreshTokenPayload = (token: string) => {
const refreshTokenSecret = process.env.REFRESH_SECRET as string
const refreshTokenSecret = process.env.REFRESH_SECRET as string
return jwtVerify(token, refreshTokenSecret) as JWTPayload
return jwtVerify(token, refreshTokenSecret) as JWTPayload
}
export const accessTokenWithRefreshCookie = (userId: number, res: Response) => {
const accessToken = signAccessToken({ userId })
const accessToken = signAccessToken({ userId })
const refreshExpiryMs = parseInt(process.env.REFRESH_EXPIRY as string) * 1000
res.cookie("rt", signRefreshToken({ userId }), {
httpOnly: true,
path: "/refresh_token",
expires: new Date(new Date().getTime() + refreshExpiryMs),
})
const refreshExpiryMs = parseInt(process.env.REFRESH_EXPIRY as string) * 1000
res.cookie("rt", signRefreshToken({ userId }), {
httpOnly: true,
path: "/refresh_token",
expires: new Date(new Date().getTime() + refreshExpiryMs),
})
return accessToken
return accessToken
}
export const customAuthChecker: AuthChecker<Context> = ({ context }) => {
try {
const authHeader = context.req.headers["authorization"]
const accessToken = authHeader!.split(" ")[1]
const accessTokenPayload = verifiedAccessTokenPayload(accessToken)
context.payload = accessTokenPayload as ContextPayload
return true
} catch (error) {
throw new Error("the valid authorization header is required: " + error)
}
try {
const authHeader = context.req.headers["authorization"]
const accessToken = authHeader!.split(" ")[1]
const accessTokenPayload = verifiedAccessTokenPayload(accessToken)
context.payload = accessTokenPayload as ContextPayload
return true
} catch (error) {
throw new Error("the valid authorization header is required: " + error)
}
}
export const contextFunction = ({ req, res }: Context) => ({ req, res })
export type Context = {
req: Request
res: Response
payload?: ContextPayload
req: Request
res: Response
payload?: ContextPayload
}
type ContextPayload = {
userId: number
userId: number
}
type JWTPayload = {
userId: number
iat: number
exp?: number
userId: number
iat: number
exp?: number
ms?: number
}

Loading…
Cancel
Save