It looks like SST doesn't update my lambda functio...
# help
a
It looks like SST doesn't update my lambda functions at all. Because the old headers are returned to me and the console does not show the function invocations, even when they have already occurred
How do I even have other headers if
cors
is false
f
Hey @Artemiy Davydov there are a couple of questions you are asking: 1. SST doesn’t update my lambda functions 2. The old headers are returned to me 3. Console does not show the function invocations Let’s look at 3 first.
Can I see how you are creating the
Api
and the code for this Lambda function?
f
Are you not able to receive invocations in your SST Console from any of the routes?
a
Lambda code is quite hacky. wrapper:
Copy code
import {
  APIGatewayProxyEventV2,
  APIGatewayProxyStructuredResultV2,
} from "aws-lambda";
import Joi from "joi";
import { User } from "models/user";
import { auth } from "libs/auth";
import cookie from "cookie";

const defaultHeaders = (event: APIGatewayProxyEventV2) => ({
  "Access-Control-Request-Headers":
    "Origin, X-Requested-With, Content-Type, Accept",
  "Access-Control-Request-Method": "OPTIONS, POST, GET, PUT",
  "Access-Control-Allow-Origin": event.headers.origin || "",
  "Access-Control-Allow-Credentials": "true",
});

/* eslint-disable @typescript-eslint/no-explicit-any */

const logic = async <T>(
  event: APIGatewayProxyEventV2,
  schema: Joi.ObjectSchema<T>,
  handler: (
    data: T & { user: User }
  ) => Promise<APIGatewayProxyStructuredResultV2 | Record<string, unknown>>,
  user: User,
  plain?: boolean
): Promise<APIGatewayProxyStructuredResultV2> => {
  const data =
    event.requestContext.http.method.toLowerCase() === "get"
      ? { ...event.pathParameters, ...event.queryStringParameters }
      : { ...event.pathParameters, ...JSON.parse(event.body ?? "") };
  const validator = schema.validate(data);
  if (validator.error) {
    return {
      statusCode: 400,
      headers: defaultHeaders(event),
    };
  }
  try {
    const data = await handler({ ...validator.value, user });
    return plain
      ? {
          ...data,
          ...{
            headers: {
              ...(data as APIGatewayProxyStructuredResultV2).headers,
              ...defaultHeaders(event),
            },
          },
        }
      : {
          statusCode: 200,
          body: JSON.stringify(data, null, 2),
          headers: defaultHeaders(event),
        };
  } catch (error) {
    console.error(error);

    return {
      statusCode: 500,
      headers: defaultHeaders(event),
    };
  }
};

export const wrapper = async <T>(
  event: APIGatewayProxyEventV2,
  schema: Joi.ObjectSchema<T>,
  handler: (
    data: T & { user: User }
  ) => Promise<APIGatewayProxyStructuredResultV2 | { [key: string]: any }>,
  isNeedToAuth = false,
  plain = false
): Promise<APIGatewayProxyStructuredResultV2> => {
  const { token } = cookie.parse(event.headers.cookie || "");

  if (isNeedToAuth) {
    try {
      if (!token) return { statusCode: 401, headers: defaultHeaders(event) };
      try {
        const { email = "" } = await auth.getTokenInfo(token);
        const user = { email, token };
        return await logic(event, schema, handler, user, plain);
      } catch (error) {
        console.error(error);
        return { statusCode: 401, headers: defaultHeaders(event) };
      }
    } catch (error) {
      console.error(error);
      return { statusCode: 500, headers: defaultHeaders(event) };
    }
  } else return await logic(event, schema, handler, undefined as any, plain);
};
users/me/handler.ts for example
Copy code
import { APIGatewayProxyEventV2, APIGatewayProxyResultV2 } from "aws-lambda";
import { wrapper } from "libs/wrapper";
import { schema } from "./schema";

export const main = (
  event: APIGatewayProxyEventV2
): Promise<APIGatewayProxyResultV2> => {
  return wrapper(event, schema, async ({ user }) => user, true);
};
f
If you try curling from ur terminal? ie.
Copy code
curl <https://ioe7hbv67f.execute-api.us-east-1.amazonaws.com/123>
What response do you get in the terminal?
a
@Frank As I understand it, I don't see any invocations because there really weren't any due to CORS errors.
If I make a direct request, then everything is fine
f
Ah I see.
a
As I understand it, the only real problem is #2
f
I think there are some confusions around CORS. So by enabling
cors: true
on the API, that doesn’t add CORS headers to the response for the API routes u defined.
When you enable
cors: true
, a new
OPTION
route is added.
And that
OPTION
route has the CORS headers in its response.
Let me know if that makes sense.
a
The problem is that even with
cors
turned off (false), headers that should not be returned (these are old headers)
f
headers that should not be returned (these are old headers)
Are you referring to the headers you are returning inside ur Lambda function? ie.
Copy code
const defaultHeaders = (event: APIGatewayProxyEventV2) => ({
  "Access-Control-Request-Headers":
    "Origin, X-Requested-With, Content-Type, Accept",
  "Access-Control-Request-Method": "OPTIONS, POST, GET, PUT",
  "Access-Control-Allow-Origin": event.headers.origin || "",
  "Access-Control-Allow-Credentials": "true",
});
a
I'm talking now, for example, about
expose-headers
. Even with
cors
is false
These are headers from an outdated stack definition
f
Is this from an OPTION request made by the browser?
a
Yes, it looks like a preflight request. But in dev tools for some reason it is shown as a GET request, not an OPTION
f
I'm stepping away from keyboard for 15min. Will follow up in a bit
@Artemiy Davydov back
Can you try setting
cors: true
and see if the these requests get through preflight check?
a
@Frank Still wrong headers
(I also recreated the stack)
f
This is with
cors:true
right?
Right. And by
Still wrong headers
, you mean this field?
a
It seems like there should be all the headers that I specified in the function, isn't it?
f
This
access-control-allow-origin
is returned by ur Lambda function right?
Just to clarify, with
cors:true
, the
OPTION
request succeeds now. And the
GET
request is failing with 500. And this
access-control-allow-origin
is in the response header of the
GET
request. Correct?
a
The function should return
headers.origin
instead of
*
for
access-control-allow-origin