refactor(SW-188): replace anon or auth procedure with serviceProcedure
This commit is contained in:
@@ -16,10 +16,4 @@ export namespace endpoints {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getHotelEndpoint = (hotelId: string | number) =>
|
export type Endpoint = endpoints.v0 | endpoints.v1
|
||||||
`${endpoints.v1.hotels}/${hotelId}` as const
|
|
||||||
|
|
||||||
export type Endpoint =
|
|
||||||
| endpoints.v0
|
|
||||||
| endpoints.v1
|
|
||||||
| ReturnType<typeof getHotelEndpoint>
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import type {
|
|||||||
} from "@/types/fetch"
|
} from "@/types/fetch"
|
||||||
import type { Endpoint } from "./endpoints"
|
import type { Endpoint } from "./endpoints"
|
||||||
|
|
||||||
export { endpoints, getHotelEndpoint } from "./endpoints"
|
export { endpoints } from "./endpoints"
|
||||||
|
|
||||||
const defaultOptions: RequestInit = {
|
const defaultOptions: RequestInit = {
|
||||||
cache: "no-store",
|
cache: "no-store",
|
||||||
@@ -27,7 +27,7 @@ const fetch = fetchRetry(global.fetch, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
export async function get(
|
export async function get(
|
||||||
endpoint: Endpoint,
|
endpoint: Endpoint | `${Endpoint}/${string}`,
|
||||||
options: RequestOptionsWithOutBody,
|
options: RequestOptionsWithOutBody,
|
||||||
params?: URLSearchParams
|
params?: URLSearchParams
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
import * as api from "@/lib/api"
|
import * as api from "@/lib/api"
|
||||||
import { getHotelEndpoint } from "@/lib/api/endpoints"
|
|
||||||
import { badRequestError } from "@/server/errors/trpc"
|
import { badRequestError } from "@/server/errors/trpc"
|
||||||
import {
|
import { publicProcedure, router, serviceProcedure } from "@/server/trpc"
|
||||||
anonymousOrAuthProcedure,
|
import { toApiLang } from "@/server/utils"
|
||||||
publicProcedure,
|
|
||||||
router,
|
|
||||||
} from "@/server/trpc"
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getFiltersInputSchema,
|
getFiltersInputSchema,
|
||||||
@@ -21,28 +17,28 @@ import {
|
|||||||
import tempFilterData from "./tempFilterData.json"
|
import tempFilterData from "./tempFilterData.json"
|
||||||
// import tempHotelData from "./tempHotelData.json"
|
// import tempHotelData from "./tempHotelData.json"
|
||||||
import tempRatesData from "./tempRatesData.json"
|
import tempRatesData from "./tempRatesData.json"
|
||||||
import { toApiLang } from "./utils"
|
|
||||||
|
|
||||||
export const hotelQueryRouter = router({
|
export const hotelQueryRouter = router({
|
||||||
getHotel: anonymousOrAuthProcedure
|
getHotel: serviceProcedure
|
||||||
.input(getHotelInputSchema)
|
.input(getHotelInputSchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const { hotelId, language, include } = input
|
const { hotelId, language, include } = input
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
|
|
||||||
const apiLang = toApiLang(language)
|
const apiLang = toApiLang(language)
|
||||||
params.set("language", apiLang)
|
params.set("language", apiLang)
|
||||||
|
|
||||||
if (include) {
|
if (include) {
|
||||||
params.set("include", include.join(","))
|
params.set("include", include.join(","))
|
||||||
}
|
}
|
||||||
|
|
||||||
const authToken = await ctx.getToken()
|
|
||||||
const apiResponse = await api.get(
|
const apiResponse = await api.get(
|
||||||
getHotelEndpoint(hotelId),
|
`${api.endpoints.v1.hotels}/${hotelId}`,
|
||||||
{
|
{
|
||||||
cache: "no-store",
|
cache: "no-store",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${authToken}`,
|
Authorization: `Bearer ${ctx.serviceToken}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
params
|
params
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import { Lang } from "@/constants/languages"
|
|
||||||
|
|
||||||
const langMap: { [key in Lang]: string } = {
|
|
||||||
[Lang.en]: "En",
|
|
||||||
[Lang.sv]: "Sv",
|
|
||||||
[Lang.no]: "No",
|
|
||||||
[Lang.fi]: "Fi",
|
|
||||||
[Lang.da]: "Da",
|
|
||||||
[Lang.de]: "De",
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to convert Lang enum to uppercase
|
|
||||||
* Needed for the Hotel endpoint.
|
|
||||||
*/
|
|
||||||
export const toApiLang = (lang: Lang): string => {
|
|
||||||
const result = langMap[lang]
|
|
||||||
if (!result) {
|
|
||||||
throw new Error("Invalid language")
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
@@ -4,27 +4,23 @@ import { ServiceTokenResponse } from "@/types/tokens"
|
|||||||
|
|
||||||
const SERVICE_TOKEN_REVALIDATE_SECONDS = 3599 // 59 minutes and 59 seconds.
|
const SERVICE_TOKEN_REVALIDATE_SECONDS = 3599 // 59 minutes and 59 seconds.
|
||||||
|
|
||||||
async function fetchServiceToken(): Promise<ServiceTokenResponse> {
|
export async function fetchServiceToken(): Promise<ServiceTokenResponse> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(`${env.CURITY_ISSUER_USER}/oauth/v2/token`, {
|
||||||
`${env.CURITY_ISSUER_SERVICE}/oauth/v2/token`,
|
method: "POST",
|
||||||
{
|
headers: {
|
||||||
method: "POST",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
headers: {
|
Accept: "application/json",
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
},
|
||||||
Accept: "application/json",
|
body: new URLSearchParams({
|
||||||
},
|
grant_type: "client_credentials",
|
||||||
body: new URLSearchParams({
|
client_id: env.CURITY_CLIENT_ID_SERVICE,
|
||||||
grant_type: "client_credentials",
|
client_secret: env.CURITY_CLIENT_SECRET_SERVICE,
|
||||||
client_id: env.CURITY_CLIENT_ID_SERVICE,
|
}),
|
||||||
client_secret: env.CURITY_CLIENT_SECRET_SERVICE,
|
next: {
|
||||||
scope: "hotel",
|
revalidate: SERVICE_TOKEN_REVALIDATE_SECONDS,
|
||||||
}),
|
},
|
||||||
next: {
|
})
|
||||||
revalidate: SERVICE_TOKEN_REVALIDATE_SECONDS,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error("Failed to obtain service token")
|
throw new Error("Failed to obtain service token")
|
||||||
@@ -36,12 +32,3 @@ async function fetchServiceToken(): Promise<ServiceTokenResponse> {
|
|||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAuthToken(userToken?: string | null): Promise<string> {
|
|
||||||
if (userToken) {
|
|
||||||
return userToken
|
|
||||||
}
|
|
||||||
|
|
||||||
const { access_token } = await fetchServiceToken()
|
|
||||||
return access_token
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import { env } from "@/env/server"
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
badRequestError,
|
badRequestError,
|
||||||
|
internalServerError,
|
||||||
sessionExpiredError,
|
sessionExpiredError,
|
||||||
unauthorizedError,
|
unauthorizedError,
|
||||||
} from "./errors/trpc"
|
} from "./errors/trpc"
|
||||||
import { getAuthToken } from "./tokenManager"
|
import { fetchServiceToken } from "./tokenManager"
|
||||||
import { transformer } from "./transformer"
|
import { transformer } from "./transformer"
|
||||||
import { langInput } from "./utils"
|
import { langInput } from "./utils"
|
||||||
|
|
||||||
@@ -101,16 +102,14 @@ export const safeProtectedProcedure = t.procedure.use(async function (opts) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
export const anonymousOrAuthProcedure = t.procedure.use(async function (opts) {
|
export const serviceProcedure = t.procedure.use(async (opts) => {
|
||||||
const session: Session | null = await opts.ctx.auth()
|
const { access_token } = await fetchServiceToken()
|
||||||
const userToken = session?.token?.access_token || null
|
if (!access_token) {
|
||||||
|
throw internalServerError("Failed to obtain service token")
|
||||||
const getToken = async () => await getAuthToken(userToken)
|
}
|
||||||
|
|
||||||
return opts.next({
|
return opts.next({
|
||||||
ctx: {
|
ctx: {
|
||||||
session,
|
serviceToken: access_token,
|
||||||
getToken,
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,3 +5,24 @@ import { Lang } from "@/constants/languages"
|
|||||||
export const langInput = z.object({
|
export const langInput = z.object({
|
||||||
lang: z.nativeEnum(Lang),
|
lang: z.nativeEnum(Lang),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to convert Lang enum to uppercase
|
||||||
|
* Needed for the Hotel endpoint.
|
||||||
|
*/
|
||||||
|
export const toApiLang = (lang: Lang): string => {
|
||||||
|
const result = toApiLangMap[lang]
|
||||||
|
if (!result) {
|
||||||
|
throw new Error("Invalid language")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
const toApiLangMap: { [key in Lang]: string } = {
|
||||||
|
[Lang.en]: "En",
|
||||||
|
[Lang.sv]: "Sv",
|
||||||
|
[Lang.no]: "No",
|
||||||
|
[Lang.fi]: "Fi",
|
||||||
|
[Lang.da]: "Da",
|
||||||
|
[Lang.de]: "De",
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user