Compare commits

...

1 commit

Author SHA1 Message Date
Krzysztof Wolski
8859c145aa WIP improve logging 2023-06-16 11:07:17 +02:00
19 changed files with 6842 additions and 6910 deletions

View file

@ -5,11 +5,7 @@ import { protectedClientProcedure } from "../trpc/protected-client-procedure";
export const channelsRouter = router({
fetch: protectedClientProcedure.query(async ({ ctx }) => {
const client = createClient(ctx.saleorApiUrl, async () =>
Promise.resolve({ token: ctx.appToken })
);
const fetcher = new ChannelsFetcher(client);
const fetcher = new ChannelsFetcher(ctx.apiClient);
return await fetcher.fetchChannels().then((channels) => channels ?? []);
}),

View file

@ -28,7 +28,7 @@ export const sendEventMessages = async ({
client,
}: SendEventMessagesArgs) => {
const logger = createLogger({
fn: "sendEventMessages",
name: "sendEventMessages",
});
logger.debug("Function called");

View file

@ -5,7 +5,7 @@ import { sendgridTransformV1toV2 } from "./sendgrid-transform-v1-to-v2";
import { createLogger } from "@saleor/apps-shared";
const logger = createLogger({
fn: "sendgridConfigMigrationV1ToV2",
name: "sendgridConfigMigrationV1ToV2",
});
interface SendgridConfigMigrationV1ToV1Args {

View file

@ -1,4 +1,3 @@
import { createLogger } from "@saleor/apps-shared";
import {
sendgridConfigurationIdInputSchema,
sendgridCreateConfigurationInputSchema,
@ -55,37 +54,30 @@ export const throwTrpcErrorFromConfigurationServiceError = (
* Allow access only for the dashboard users and attaches the
* configuration service to the context
*/
const protectedWithConfigurationService = protectedClientProcedure.use(({ next, ctx }) =>
next({
ctx: {
...ctx,
sendgridConfigurationService: new SendgridConfigurationService({
metadataManager: new SendgridPrivateMetadataManager(
createSettingsManager(ctx.apiClient, ctx.appId!),
ctx.saleorApiUrl
),
}),
},
})
const protectedWithConfigurationService = protectedClientProcedure.use(
({ next, ctx: { authData, apiClient } }) =>
next({
ctx: {
sendgridConfigurationService: new SendgridConfigurationService({
metadataManager: new SendgridPrivateMetadataManager(
createSettingsManager(apiClient, authData.appId),
authData.saleorApiUrl
),
}),
},
})
);
export const sendgridConfigurationRouter = router({
fetch: protectedWithConfigurationService.query(async ({ ctx }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug("sendgridConfigurationRouter.fetch called");
return ctx.sendgridConfigurationService.getConfigurationRoot();
}),
getConfiguration: protectedWithConfigurationService
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridConfigurationIdInputSchema)
.query(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.get called");
ctx.logger.debug(`Getting configuration ${input.id} from configuration service`);
try {
return ctx.sendgridConfigurationService.getConfiguration(input);
return await ctx.sendgridConfigurationService.getConfiguration(input);
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
@ -93,12 +85,10 @@ export const sendgridConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridGetConfigurationsInputSchema)
.query(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.getConfigurations called");
try {
return ctx.sendgridConfigurationService.getConfigurations(input);
return await ctx.sendgridConfigurationService.getConfigurations(input);
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
@ -106,27 +96,26 @@ export const sendgridConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridCreateConfigurationInputSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.create called");
const newConfiguration = {
...sendgridDefaultEmptyConfigurations.configuration(),
...input,
};
return await ctx.sendgridConfigurationService.createConfiguration(newConfiguration);
try {
return await ctx.sendgridConfigurationService.createConfiguration(newConfiguration);
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
deleteConfiguration: protectedWithConfigurationService
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridConfigurationIdInputSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.delete called");
try {
await ctx.sendgridConfigurationService.deleteConfiguration(input);
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
@ -134,16 +123,13 @@ export const sendgridConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridGetEventConfigurationInputSchema)
.query(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.getEventConfiguration called");
try {
return await ctx.sendgridConfigurationService.getEventConfiguration({
configurationId: input.configurationId,
eventType: input.eventType,
});
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
@ -151,13 +137,10 @@ export const sendgridConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridUpdateBasicInformationSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.updateBasicInformation called");
try {
return await ctx.sendgridConfigurationService.updateConfiguration({ ...input });
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
@ -165,13 +148,10 @@ export const sendgridConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridUpdateApiConnectionSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.updateApiConnection called");
try {
return await ctx.sendgridConfigurationService.updateConfiguration({ ...input });
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
@ -180,10 +160,6 @@ export const sendgridConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridUpdateSenderSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.updateBasicInformation called");
const configuration = await ctx.sendgridConfigurationService.getConfiguration({
id: input.id,
});
@ -196,6 +172,7 @@ export const sendgridConfigurationRouter = router({
const chosenSender = senders.find((s) => s.value === input.sender);
if (!chosenSender) {
ctx.logger.debug({ input }, "Throwing error - sender does not exist");
throw new TRPCError({
code: "BAD_REQUEST",
message: "Sender does not exist",
@ -210,6 +187,7 @@ export const sendgridConfigurationRouter = router({
sender: input.sender,
});
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
@ -217,10 +195,6 @@ export const sendgridConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(updateChannelsInputSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.updateChannels called");
try {
return await ctx.sendgridConfigurationService.updateConfiguration({
id: input.id,
@ -231,6 +205,7 @@ export const sendgridConfigurationRouter = router({
},
});
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
@ -239,10 +214,6 @@ export const sendgridConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridUpdateEventSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.updateEvent called");
const { id: configurationId, eventType, ...eventConfiguration } = input;
try {
@ -252,6 +223,7 @@ export const sendgridConfigurationRouter = router({
eventConfiguration,
});
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
}),
@ -260,10 +232,6 @@ export const sendgridConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(sendgridUpdateEventArraySchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "sendgridConfigurationRouter.updateEventArray called");
return await Promise.all(
input.events.map(async (event) => {
const { eventType, ...eventConfiguration } = event;
@ -275,6 +243,7 @@ export const sendgridConfigurationRouter = router({
eventConfiguration,
});
} catch (e) {
ctx.logger.debug({ error: e }, `Service has thrown an error`);
throwTrpcErrorFromConfigurationServiceError(e);
}
})

View file

@ -11,7 +11,7 @@ import { filterConfigurations } from "../../app-configuration/filter-configurati
import { SendgridPrivateMetadataManager } from "./sendgrid-metadata-manager";
const logger = createLogger({
service: "SendgridConfigurationService",
name: "SendgridConfigurationService",
});
export type SendgridConfigurationServiceErrorType =

View file

@ -5,7 +5,7 @@ import { sendgridConfigMigrationV1ToV2 } from "./migrations/sendgrid-config-migr
import { createLogger } from "@saleor/apps-shared";
const logger = createLogger({
fn: "SendgridPrivateMetadataManager",
name: "SendgridPrivateMetadataManager",
});
export class SendgridPrivateMetadataManager {

View file

@ -24,7 +24,7 @@ export const sendSendgrid = async ({
sendgridConfiguration,
}: SendSendgridArgs) => {
const logger = createLogger({
fn: "sendSendgrid",
name: "sendSendgrid",
event,
});

View file

@ -2,7 +2,7 @@ import Handlebars from "handlebars";
import { createLogger } from "@saleor/apps-shared";
const logger = createLogger({
fn: "compileHandlebarsTemplate",
name: "compileHandlebarsTemplate",
});
export const compileHandlebarsTemplate = (template: string, variables: any) => {

View file

@ -2,7 +2,7 @@ import mjml2html from "mjml";
import { createLogger } from "@saleor/apps-shared";
const logger = createLogger({
fn: "compileMjml",
name: "compileMjml",
});
export const compileMjml = (mjml: string) => {

View file

@ -9,7 +9,7 @@ import { smtpTransformV1toV2 } from "./smtp-transform-v1-to-v2";
import { createLogger } from "@saleor/apps-shared";
const logger = createLogger({
fn: "smtpConfigMigrationV1ToV2",
name: "smtpConfigMigrationV1ToV2",
});
interface SmtpConfigMigrationV1ToV1Args {

View file

@ -1,4 +1,3 @@
import { createLogger } from "@saleor/apps-shared";
import {
SmtpConfigurationService,
SmtpConfigurationServiceError,
@ -58,35 +57,30 @@ export const throwTrpcErrorFromConfigurationServiceError = (
* Allow access only for the dashboard users and attaches the
* configuration service to the context
*/
const protectedWithConfigurationService = protectedClientProcedure.use(({ next, ctx }) =>
next({
ctx: {
...ctx,
smtpConfigurationService: new SmtpConfigurationService({
metadataManager: new SmtpPrivateMetadataManager(
createSettingsManager(ctx.apiClient, ctx.appId!),
ctx.saleorApiUrl
),
}),
},
})
const protectedWithConfigurationService = protectedClientProcedure.use(
({ next, ctx: { authData, apiClient } }) =>
next({
ctx: {
smtpConfigurationService: new SmtpConfigurationService({
metadataManager: new SmtpPrivateMetadataManager(
createSettingsManager(apiClient, authData.appId),
authData.saleorApiUrl
),
}),
},
})
);
export const smtpConfigurationRouter = router({
fetch: protectedWithConfigurationService.query(async ({ ctx }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug("smtpConfigurationRouter.fetch called");
ctx.logger.debug("smtpConfigurationRouter.fetch called");
return ctx.smtpConfigurationService.getConfigurationRoot();
}),
getConfiguration: protectedWithConfigurationService
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpConfigurationIdInputSchema)
.query(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.get called");
ctx.logger.debug(input, "Getting configuration");
try {
return ctx.smtpConfigurationService.getConfiguration(input);
} catch (e) {
@ -97,9 +91,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpGetConfigurationsInputSchema)
.query(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.getConfigurations called");
ctx.logger.debug(input, "Getting configurations");
try {
return ctx.smtpConfigurationService.getConfigurations(input);
} catch (e) {
@ -110,9 +102,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpCreateConfigurationInputSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.create called");
ctx.logger.debug({ configurationName: input.name }, "Creating a new configuration");
const newConfiguration = {
...smtpDefaultEmptyConfigurations.configuration(),
...input,
@ -124,9 +114,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpConfigurationIdInputSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.delete called");
ctx.logger.debug(input, "Delete configuration");
try {
await ctx.smtpConfigurationService.deleteConfiguration(input);
@ -138,9 +126,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpGetEventConfigurationInputSchema)
.query(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.getEventConfiguration or create called");
ctx.logger.debug(input, "Getting event configuration");
try {
return await ctx.smtpConfigurationService.getEventConfiguration({
@ -162,10 +148,9 @@ export const smtpConfigurationRouter = router({
})
)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "mjmlConfigurationRouter.renderTemplate called");
ctx.logger.debug(input, "Rendering submitted MJML template");
// TODO: Extract rendering to the separate function
let renderedSubject = "";
const payload = JSON.parse(input.payload);
@ -173,7 +158,6 @@ export const smtpConfigurationRouter = router({
if (input.subject) {
const compiledSubjectTemplate = Handlebars.compile(input.subject);
logger.warn("subject part");
renderedSubject = compiledSubjectTemplate(payload);
}
@ -190,6 +174,8 @@ export const smtpConfigurationRouter = router({
}
}
ctx.logger.debug("Render successful");
return {
renderedSubject,
renderedEmailBody: renderedEmail,
@ -200,9 +186,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpUpdateBasicInformationSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.updateBasicInformation called");
ctx.logger.debug(input, "Updating the configuration");
try {
return await ctx.smtpConfigurationService.updateConfiguration({ ...input });
@ -215,9 +199,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpUpdateSmtpSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.updateSmtp called");
ctx.logger.debug({ configurationId: input.id }, "Updating the configuration");
try {
return await ctx.smtpConfigurationService.updateConfiguration({ ...input });
@ -230,9 +212,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpUpdateSenderSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.updateSender called");
ctx.logger.debug(input, "Updating the configuration");
try {
return await ctx.smtpConfigurationService.updateConfiguration({ ...input });
@ -245,9 +225,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(updateChannelsInputSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.updateChannels called");
ctx.logger.debug(input, "Updating the configuration");
try {
return await ctx.smtpConfigurationService.updateConfiguration({
@ -267,9 +245,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpUpdateEventSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.updateEvent called");
ctx.logger.debug(input, "Updating the event");
const { id: configurationId, eventType, ...eventConfiguration } = input;
@ -287,9 +263,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpUpdateEventActiveStatusInputSchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "mjmlConfigurationRouter.updateEventActiveStatus called");
ctx.logger.debug(input, "Updating the event");
try {
return await ctx.smtpConfigurationService.updateEventConfiguration({
configurationId: input.id,
@ -306,9 +280,7 @@ export const smtpConfigurationRouter = router({
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
.input(smtpUpdateEventArraySchema)
.mutation(async ({ ctx, input }) => {
const logger = createLogger({ saleorApiUrl: ctx.saleorApiUrl });
logger.debug(input, "smtpConfigurationRouter.updateEventArray called");
ctx.logger.debug(input, "Updating events");
return await Promise.all(
input.events.map(async (event) => {

View file

@ -5,7 +5,7 @@ import { smtpConfigMigrationV1ToV2 } from "./migrations/smtp-config-migration-v1
import { createLogger } from "@saleor/apps-shared";
const logger = createLogger({
fn: "SmtpPrivateMetadataManager",
name: "SmtpPrivateMetadataManager",
});
export class SmtpPrivateMetadataManager {

View file

@ -2,7 +2,7 @@ import { convert } from "html-to-text";
import { createLogger } from "@saleor/apps-shared";
const logger = createLogger({
fn: "htmlToPlaintext",
name: "htmlToPlaintext",
});
export const htmlToPlaintext = (html: string) => {

View file

@ -2,7 +2,7 @@ import nodemailer from "nodemailer";
import { createLogger } from "@saleor/apps-shared";
const logger = createLogger({
fn: "sendEmailWithSmtp",
name: "sendEmailWithSmtp",
});
export interface SendMailArgs {

View file

@ -27,7 +27,7 @@ export const sendSmtp = async ({
smtpConfiguration,
}: SendSmtpArgs) => {
const logger = createLogger({
fn: "sendSmtp",
name: "sendSmtp",
event,
});

View file

@ -0,0 +1,32 @@
import { createLogger } from "@saleor/apps-shared";
import { middleware } from "../trpc-server";
export const attachLogger = middleware(async ({ ctx, next, type, path }) => {
const loggerName = `tRPC ${type} ${path.replace(/\./g, "/")}`;
const logger = createLogger({
name: loggerName,
requestType: type,
path,
saleorApiUrl: ctx.saleorApiUrl,
});
const start = Date.now();
logger.info(`Requested received`);
const result = await next({
ctx: {
logger,
},
});
const durationMs = Date.now() - start;
if (result.ok) {
logger.info({ durationMs }, `Response successful`);
} else {
logger.info({ durationMs }, `Response with error`);
}
return result;
});

View file

@ -3,21 +3,27 @@ import { middleware, procedure } from "./trpc-server";
import { TRPCError } from "@trpc/server";
import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next";
import { saleorApp } from "../../saleor-app";
import { logger } from "@saleor/apps-shared";
import { createClient } from "../../lib/create-graphql-client";
import { attachLogger } from "./middlewares/attach-logger";
import { createLogger } from "@saleor/apps-shared";
const attachAppToken = middleware(async ({ ctx, next }) => {
logger.debug("attachAppToken middleware");
const attachSaleorAuthData = middleware(async ({ ctx, next }) => {
const logger = createLogger({
name: "attachSaleorAuthData",
saleorApiUrl: ctx.saleorApiUrl,
});
if (!ctx.saleorApiUrl) {
logger.debug("ctx.saleorApiUrl not found, throwing");
throw new TRPCError({
code: "BAD_REQUEST",
message: "Missing saleorApiUrl in request",
message: "Missing saleorApiUrl header in request",
});
}
logger.debug("Check if APL has registration given saleorApiUrl");
const authData = await saleorApp.apl.get(ctx.saleorApiUrl);
if (!authData) {
@ -31,70 +37,47 @@ const attachAppToken = middleware(async ({ ctx, next }) => {
return next({
ctx: {
appToken: authData.token,
saleorApiUrl: authData.saleorApiUrl,
appId: authData.appId,
authData,
},
});
});
const validateClientToken = middleware(async ({ ctx, next, meta }) => {
logger.debug(
{
permissions: meta?.requiredClientPermissions,
},
"Calling validateClientToken middleware with permissions required"
);
if (!ctx.token) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Missing token in request. This middleware can be used only in frontend",
const validateClientToken = attachSaleorAuthData.unstable_pipe(
async ({ ctx: { authData, appBridgeToken }, next, meta }) => {
const logger = createLogger({
name: "validateClientToken",
requiredPermissions: meta?.requiredClientPermissions,
saleorApiUrl: authData.saleorApiUrl,
});
}
if (!ctx.appId) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Missing appId in request. This middleware can be used after auth is attached",
});
}
if (!appBridgeToken) {
logger.debug("Missing JWT token in the request.");
throw new TRPCError({
code: "UNAUTHORIZED",
message: "Missing JWT token in the request.",
});
}
if (!ctx.saleorApiUrl) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message:
"Missing saleorApiUrl in request. This middleware can be used after auth is attached",
});
}
logger.debug("Verify JWT token");
if (!ctx.ssr) {
try {
logger.debug("trying to verify JWT token from frontend");
logger.debug({ token: ctx.token ? `${ctx.token[0]}...` : undefined });
await verifyJWT({
appId: ctx.appId,
token: ctx.token,
saleorApiUrl: ctx.saleorApiUrl,
appId: authData.appId,
token: appBridgeToken,
saleorApiUrl: authData.saleorApiUrl,
requiredPermissions: meta?.requiredClientPermissions ?? [],
});
} catch (e) {
logger.debug("JWT verification failed, throwing");
logger.debug("JWT verification failed, throwing error");
throw new ProtectedHandlerError("JWT verification failed: ", "JWT_VERIFICATION_FAILED");
}
}
return next({
ctx: {
...ctx,
saleorApiUrl: ctx.saleorApiUrl,
},
});
});
return next();
}
);
/**
* Construct common graphQL client and attach it to the context
* Construct common GraphQL client and attach it to the context
*
* Can be used only if called from the frontend (react-query),
* otherwise jwks validation will fail (if createCaller used)
@ -102,18 +85,14 @@ const validateClientToken = middleware(async ({ ctx, next, meta }) => {
* TODO Rethink middleware composition to enable safe server-side router calls
*/
export const protectedClientProcedure = procedure
.use(attachAppToken)
.use(attachLogger)
.use(validateClientToken)
.use(async ({ ctx, next }) => {
const client = createClient(ctx.saleorApiUrl, async () =>
Promise.resolve({ token: ctx.appToken })
);
return next({
.use(async ({ ctx: { authData }, next }) =>
next({
ctx: {
apiClient: client,
appToken: ctx.appToken,
saleorApiUrl: ctx.saleorApiUrl,
apiClient: createClient(authData.saleorApiUrl, async () =>
Promise.resolve({ token: authData.token })
),
},
});
});
})
);

View file

@ -4,10 +4,8 @@ import { inferAsyncReturnType } from "@trpc/server";
export const createTrpcContext = async ({ res, req }: trpcNext.CreateNextContextOptions) => {
return {
token: req.headers[SALEOR_AUTHORIZATION_BEARER_HEADER] as string | undefined,
appBridgeToken: req.headers[SALEOR_AUTHORIZATION_BEARER_HEADER] as string | undefined,
saleorApiUrl: req.headers[SALEOR_API_URL_HEADER] as string | undefined,
appId: undefined as undefined | string,
ssr: undefined as undefined | boolean,
};
};

File diff suppressed because it is too large Load diff