feat: (Web-210) Added encryption for my-booking Urls
This commit is contained in:
@@ -31,6 +31,8 @@ SEAMLESS_LOGOUT_FI="http://www.example.fi/updatelogout?newweb=1"
|
||||
SEAMLESS_LOGOUT_NO="http://www.example.no/updatelogout?newweb=1"
|
||||
SEAMLESS_LOGOUT_SV="http://www.example.sv/updatelogout?newweb=1"
|
||||
WEBVIEW_ENCRYPTION_KEY="MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI="
|
||||
BOOKING_ENCRYPTION_KEY=za2paS0x
|
||||
NODE_OPTIONS=--openssl-legacy-provider
|
||||
|
||||
PUBLIC_URL="http://localhost:3000"
|
||||
AUTH_URL="$PUBLIC_URL/api/web/auth"
|
||||
|
||||
@@ -3,6 +3,7 @@ import { dt } from "@/lib/dt"
|
||||
import { CalendarIcon } from "@/components/Icons"
|
||||
import Image from "@/components/Image"
|
||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||
|
||||
import styles from "./stay.module.css"
|
||||
@@ -10,7 +11,9 @@ import styles from "./stay.module.css"
|
||||
import type { StayCardProps } from "@/types/components/myPages/stays/stayCard"
|
||||
|
||||
export default function StayCard({ stay, lang }: StayCardProps) {
|
||||
const { checkinDate, checkoutDate, hotelInformation } = stay.attributes
|
||||
const { checkinDate, checkoutDate, hotelInformation, bookingUrl } =
|
||||
stay.attributes
|
||||
|
||||
const arrival = dt(checkinDate).locale(lang)
|
||||
const arrivalDate = arrival.format("DD MMM")
|
||||
const arrivalDateTime = arrival.format("YYYY-MM-DD")
|
||||
|
||||
@@ -61,6 +61,7 @@ export const getStaysSchema = z.object({
|
||||
checkinDate: z.string(),
|
||||
checkoutDate: z.string(),
|
||||
isWebAppOrigin: z.boolean(),
|
||||
bookingUrl: z.string().optional(),
|
||||
}),
|
||||
relationships: z.object({
|
||||
hotel: z.object({
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
getUserInputSchema,
|
||||
staysInput,
|
||||
} from "./input"
|
||||
import encryptValue from "../utils/encryptValue"
|
||||
import {
|
||||
getCreditCardsSchema,
|
||||
getFriendTransactionsSchema,
|
||||
@@ -212,6 +213,61 @@ export const userQueryRouter = router({
|
||||
? verifiedData.data.links.offset
|
||||
: undefined
|
||||
|
||||
// Tenporary till we have user name in ctx session data
|
||||
// ----
|
||||
const apiResponseUser = await api.get(api.endpoints.v1.profile, {
|
||||
cache: "no-store",
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
})
|
||||
|
||||
if (!apiResponseUser.ok) {
|
||||
// switch (apiResponseUser.status) {
|
||||
// case 400:
|
||||
// throw badRequestError(apiResponseUser)
|
||||
// case 401:
|
||||
// throw unauthorizedError(apiResponseUser)
|
||||
// case 403:
|
||||
// throw forbiddenError(apiResponseUser)
|
||||
// default:
|
||||
// throw internalServerError(apiResponseUser)
|
||||
// }
|
||||
console.info(`API Response Failed - Getting User`)
|
||||
console.info(`User: (${JSON.stringify(ctx.session.user)})`)
|
||||
console.error(apiResponse)
|
||||
return null
|
||||
}
|
||||
|
||||
const apiJsonUser = await apiResponse.json()
|
||||
if (!apiJson.data?.attributes) {
|
||||
// throw notFound(apiJson)
|
||||
console.error(
|
||||
`User has no data - (user: ${JSON.stringify(ctx.session.user)})`
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
const verifiedDataUser = getUserSchema.safeParse(apiJsonUser.data.attributes)
|
||||
if (!verifiedDataUser.success) {
|
||||
console.info(
|
||||
`Failed to validate User - (User: ${JSON.stringify(ctx.session.user)})`
|
||||
)
|
||||
console.error(verifiedDataUser.error)
|
||||
return null
|
||||
}
|
||||
// ------------------
|
||||
|
||||
verifiedData.data.data.forEach((stay) => {
|
||||
const originalString =
|
||||
stay.attributes.confirmationNumber.toString() +
|
||||
"," +
|
||||
verifiedDataUser.data.lastName
|
||||
let bookingUrl = encryptValue(originalString)
|
||||
stay.attributes.bookingUrl =
|
||||
"/hotelreservation/my-booking?RefId=" + bookingUrl
|
||||
})
|
||||
|
||||
return {
|
||||
data: verifiedData.data.data,
|
||||
nextCursor,
|
||||
@@ -272,6 +328,61 @@ export const userQueryRouter = router({
|
||||
? verifiedData.data.links.offset
|
||||
: undefined
|
||||
|
||||
// Tenporary till we have user name in ctx session data
|
||||
// ----
|
||||
const apiResponseUser = await api.get(api.endpoints.v1.profile, {
|
||||
cache: "no-store",
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
})
|
||||
|
||||
if (!apiResponseUser.ok) {
|
||||
// switch (apiResponseUser.status) {
|
||||
// case 400:
|
||||
// throw badRequestError(apiResponseUser)
|
||||
// case 401:
|
||||
// throw unauthorizedError(apiResponseUser)
|
||||
// case 403:
|
||||
// throw forbiddenError(apiResponseUser)
|
||||
// default:
|
||||
// throw internalServerError(apiResponseUser)
|
||||
// }
|
||||
console.info(`API Response Failed - Getting Upcoming Stays`)
|
||||
console.info(`User: (${JSON.stringify(ctx.session.user)})`)
|
||||
console.error(apiResponse)
|
||||
return null
|
||||
}
|
||||
|
||||
const apiJsonUser = await apiResponse.json()
|
||||
if (!apiJson.data?.attributes) {
|
||||
// throw notFound(apiJson)
|
||||
console.error(
|
||||
`User has no data - (user: ${JSON.stringify(ctx.session.user)})`
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
const verifiedDataUser = getUserSchema.safeParse(apiJsonUser.data.attributes)
|
||||
if (!verifiedDataUser.success) {
|
||||
console.info(
|
||||
`Failed to validate User - (User: ${JSON.stringify(ctx.session.user)})`
|
||||
)
|
||||
console.error(verifiedDataUser.error)
|
||||
return null
|
||||
}
|
||||
// ------------------
|
||||
|
||||
verifiedData.data.data.forEach((stay) => {
|
||||
const originalString =
|
||||
stay.attributes.confirmationNumber.toString() +
|
||||
"," +
|
||||
verifiedDataUser.data.lastName
|
||||
let bookingUrl = encryptValue(originalString)
|
||||
stay.attributes.bookingUrl =
|
||||
"/hotelreservation/my-booking?RefId=" + bookingUrl
|
||||
})
|
||||
|
||||
return {
|
||||
data: verifiedData.data.data,
|
||||
nextCursor,
|
||||
|
||||
18
server/routers/utils/encryptValue.ts
Normal file
18
server/routers/utils/encryptValue.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import crypto from "crypto"
|
||||
|
||||
export default function encryptValue(originalString: string) {
|
||||
const encryptionKey = process.env.BOOKING_ENCRYPTION_KEY ?? ""
|
||||
const bufferKey = Buffer.from(encryptionKey, "utf8")
|
||||
let cipher = crypto.createCipheriv("DES-ECB", bufferKey, null)
|
||||
cipher.setAutoPadding(false)
|
||||
let bufferString = Buffer.from(originalString, "utf8")
|
||||
let paddingSize = bufferKey.length - (bufferString.length % bufferKey.length)
|
||||
let paddedStr = Buffer.concat([bufferString, Buffer.alloc(paddingSize, 0)])
|
||||
let encryptedValue = cipher
|
||||
.update(paddedStr)
|
||||
.toString("base64")
|
||||
.replace(/\+/g, "-")
|
||||
cipher.final()
|
||||
|
||||
return encryptedValue
|
||||
}
|
||||
Reference in New Issue
Block a user