Skip to content

Commit

Permalink
Merge pull request #757 from supertokens/fix/revert-middy-version-cha…
Browse files Browse the repository at this point in the history
…nges

Update aws lambda docs
  • Loading branch information
rishabhpoddar authored Dec 18, 2023
2 parents 2844dfb + 7e1090e commit a0289dd
Show file tree
Hide file tree
Showing 91 changed files with 3,333 additions and 2,476 deletions.
24 changes: 24 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,30 @@ CODE_TYPE_CHECK=all npm run start

You may need to add something to the code that is necessary for type checking but shouldn't appear in the output documentation. You can do this by adding a comment to the end of the line stating: `typecheck-only, removed from output`. Lines ending with this comment will be removed from the output but kept for type checking.

Omitting substrings from the final output while retaining them for type checking can be achieved using the `__OMIT_START__` and `__OMIT_END__` specifier. This is particularly useful for incorporating type annotations into code snippets without including them in the end result. Consider the following example:

```mjs
function square(num__OMIT_START__: number__OMIT_END__) {
return num * num;
}
```

During code checking, the plugin will analyze the following code:

```mjs
function square(num: number) {
return num * num;
}
```

However, the final output will exclude type annotations:

```mjs
function square(num) {
return num * num;
}
```

#### Tips JS / TS
- If you need to purposely tell TS to ignore errors in the next line, you can add a `// @ts-ignore` comment in your code snippets. This will make the TS checker pass. The type checking engine will also remove these from the final code output so that users don't see this unnecessarily.
- If you are working with snippets that use an older version of supertokens-node you can use a custom import for that version. For example some snippets use `supertokens-node7` as the import to fix typing. The type checking engine replaces this with `supertokens-node`. NOTE: If you need to add another node version as a custom import, please modify the type checking script to replace the import statement to use `supertokens-node`
Expand Down
15 changes: 8 additions & 7 deletions v2/emailpassword/serverless/with-aws-lambda/about.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@ title: About
hide_title: true
---

<!-- COPY DOCS -->
<!-- COPY SECTION -->
<!-- ./thirdpartyemailpassword/serverless/with-aws-lambda/about.mdx -->
<!-- 1 -->

# About

## Overview steps

1. Frontend setup
2. Backend setup
3. Creating an auth serverless function to expose SuperTokens APIs to the frontend
4. AWS API Gateway setup
5. Using SuperTokens functions in your APIs (for example for session verification).
6. Next steps
3. Using SuperTokens functions in your APIs (for example for session verification).
4. Next steps

## [An example GitHub repo](https://github.com/supertokens/supertokens-auth-react/tree/master/examples/with-aws-lambda)
## [An example GitHub repo](https://github.com/supertokens/supertokens-node/tree/master/examples/aws/with-emailpassword)

<!-- END COPY SECTION -->

:::important
This example follows the "emailpassword" recipe.
The example follows the "emailpassword" recipe.
:::
36 changes: 2 additions & 34 deletions v2/emailpassword/serverless/with-aws-lambda/api-gateway-config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,9 @@ id: api-gateway-config
title: 4. Setting Up REST API Gateway & CORS
hide_title: true
---

<!-- COPY DOCS -->
<!-- ./thirdpartyemailpassword/serverless/with-aws-lambda/api-gateway-config.mdx -->

import AppInfoForm from "/src/components/appInfoForm"

# 4. Setting Up REST API Gateway & CORS

## 1) Create Proxy path for Auth APIs
- In your API Gateway, create a base path `/auth` and then create a proxy path `/auth/{proxy+}`.
- When creating the proxy path, enable both `Enable API Gateway CORS` and `Configure as proxy resource`.

<img alt="Creating a proxy path in AWS API gateway" src="/img/aws-api-gateway-proxy-create.png" />

## 2) Configure Auth APIs Lambda with API Gateway
- Create a POST method for the proxy route and associate the Auth APIs lambda function created in this [step](./auth-serverless)

<img alt="Creating a POST method in AWS API gateway" src="/img/aws-api-gateway-proxy-setup.png" />

:::important
When associating the lambda function, enable the `Lambda Proxy integration` option if available to chose. This is important because this will tell API Gateway not to modify or transform the incoming request when forwarding it to the lambda function.
:::

## 3) Enable CORS for proxy path

<AppInfoForm
askForWebsiteDomain
hideWebsiteBasePathField
>

- When enabling CORS for the proxy path, make sure to do the following:
- Add `rid,fdi-version,anti-csrf,st-auth-mode` to the existing `Access-Control-Allow-Headers`
- Set `Access-Control-Allow-Origin` to `'^{form_websiteDomain}'`
- Set `Access-Control-Allow-Credentials` to `'true'`. **Don't miss out on those quotes else it won't get configured correctly.**

<img alt="Enabling CORS for the proxy path in AWS API Gateway" src="/img/aws-api-gateway-proxy-cors.png" />
import Redirector from '/src/components/Redirector';

</AppInfoForm>
<Redirector to='./setup-api-gateway' />
86 changes: 2 additions & 84 deletions v2/emailpassword/serverless/with-aws-lambda/auth-serverless.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,88 +7,6 @@ hide_title: true
<!-- COPY DOCS -->
<!-- ./thirdpartyemailpassword/serverless/with-aws-lambda/auth-serverless.mdx -->

import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs";
import TabItem from '@theme/TabItem';
import Redirector from '/src/components/Redirector';

# 3. Exposing Auth APIs

We will add all the backend APIs for auth on `/auth/*`. This can be changed by setting the `apiBasePath` property in the `appInfo` object on the backend and frontend. For the rest of this page, we will assume you are using `/auth/*`.

## Copy this snippet to your handler file

<BackendSDKTabs disableGolang>
<TabItem value="nodejs">

An example of this can be found [here](https://github.com/supertokens/supertokens-auth-react/blob/master/examples/with-aws-lambda/backend/auth.js).

```tsx title="auth.js"
import supertokens from "supertokens-node";
import { middleware } from "supertokens-node/framework/awsLambda";
// @ts-ignore
import { getBackendConfig } from "./config";
import middy from "@middy/core";
import cors from "@middy/http-cors";

supertokens.init(getBackendConfig());

module.exports.handler = middy(middleware()).use(cors({
origin: getBackendConfig().appInfo.websiteDomain,
credentials: true,
headers: ["Content-Type", ...supertokens.getAllCORSHeaders()].join(", "),
methods: "OPTIONS,POST,GET,PUT,DELETE"
})).onError(request => {
throw request.error;
});
```

</TabItem>

<TabItem value="python">

```python title="auth.py"
import nest_asyncio # type: ignore
nest_asyncio.apply() # type: ignore

from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
from mangum import Mangum

from supertokens_python import init, get_all_cors_headers
from supertokens_python.framework.fastapi import get_middleware

import config # type: ignore

init(
supertokens_config=config.supertokens_config, # type: ignore
app_info=config.app_info, # type: ignore
framework=config.framework, # type: ignore
recipe_list=config.recipe_list, # type: ignore
mode="asgi",
)

app = FastAPI(title="SuperTokens Example")
app.add_middleware(get_middleware())

app = CORSMiddleware(
app=app,
allow_origins=[
config.app_info.website_domain # type: ignore
],
allow_credentials=True,
allow_methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"],
allow_headers=["Content-Type"] + get_all_cors_headers(),
)

handler = Mangum(app)
```

</TabItem>

</BackendSDKTabs>

:::important
Notice that we called `supertokens.init` above. We will need to call this in all API endpoints that use any functions related to supertokens.
:::


<!-- END COPY DOCS -->
<Redirector to='./setup-lambda#4-add-the-supertokens-auth-middleware' />
28 changes: 14 additions & 14 deletions v2/emailpassword/serverless/with-aws-lambda/authorizer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ You can use a lambda as an Authorizer in API Gateways. This will enable you to u

## 1) Add configurations and dependencies

Follow [step 1](./frontend) and [step 2](./backend-config).
Refer to the [frontend](./frontend), [lambda layer](./setup-lambda-layer), and [lambda setup](./setup-lambda) guides for setting up the frontend, lambda layer, and lambda function.

## 2) Add code to the lambda function handler

Expand Down Expand Up @@ -149,20 +149,20 @@ def handler(event: Dict[str, Any], context: Any):

Use the code below as the handler for the lambda. Remember that whenever we want to use any functions from the `supertokens-node` lib, we have to call the `supertokens.init` function at the top of that serverless function file. We can then use `getSession()` to get the session.

```tsx title="auth.ts"
```tsx title="index.mjs"
import supertokens from "supertokens-node";
import { SessionEvent } from "supertokens-node/framework/awsLambda";
import { APIGatewayAuthorizerEvent, PolicyDocument, Statement, AuthResponse } from "aws-lambda";
import { SessionEvent } from "supertokens-node/framework/awsLambda"; // typecheck-only, removed from output
import { APIGatewayAuthorizerEvent, PolicyDocument, Statement, AuthResponse } from "aws-lambda"; // typecheck-only, removed from output
import Session from "supertokens-node/recipe/session";

// @ts-ignore
import { getBackendConfig } from "./config";
import { getBackendConfig } from "./config.mjs";

supertokens.init(getBackendConfig());

type AuthorizerEvent = SessionEvent & APIGatewayAuthorizerEvent;
type AuthorizerEvent = SessionEvent & APIGatewayAuthorizerEvent; // typecheck-only, removed from output

exports.handler = async function (event: AuthorizerEvent) {
export const handler = async function (event__OMIT_START__: AuthorizerEvent__OMIT_END__) {
try {
const session = await Session.getSession(event, event, { sessionRequired: false });
if (session) {
Expand Down Expand Up @@ -198,22 +198,22 @@ exports.handler = async function (event: AuthorizerEvent) {
}

// Help function to generate an IAM policy
const generatePolicy = function (principalId: string, effect: string, resource: string, context?: any) {
const generatePolicy = function (principalId__OMIT_START__: string__OMIT_END__, effect__OMIT_START__: string__OMIT_END__, resource__OMIT_START__: string__OMIT_END__, context__OMIT_START__?: any__OMIT_END__) {
// Required output:
const policyDocument: PolicyDocument = {
const policyDocument__OMIT_START__: PolicyDocument__OMIT_END__ = {
Version: '2012-10-17',
Statement: [],
};

const statementOne: Statement = {
const statementOne__OMIT_START__: Statement__OMIT_END__ = {
Action: 'execute-api:Invoke',
Effect: effect,
Resource: resource,
};

policyDocument.Statement[0] = statementOne;

const authResponse: AuthResponse = {
const authResponse__OMIT_START__: AuthResponse__OMIT_END__ = {
principalId: principalId,
policyDocument: policyDocument,
// Optional output with custom properties of the String, Number or Boolean type.
Expand All @@ -223,11 +223,11 @@ const generatePolicy = function (principalId: string, effect: string, resource:
return authResponse;
}

const generateAllow = function (principalId: string, resource: string, context?: any) {
const generateAllow = function (principalId__OMIT_START__: string__OMIT_END__, resource__OMIT_START__: string__OMIT_END__, context__OMIT_START__?: any__OMIT_END__) {
return generatePolicy(principalId, 'Allow', resource, context);
};

const generateDeny = function (principalId: string, resource: string, context?: any) {
const generateDeny = function (principalId__OMIT_START__: string__OMIT_END__, resource__OMIT_START__: string__OMIT_END__, context__OMIT_START__?: any__OMIT_END__) {
return generatePolicy(principalId, 'Deny', resource, context);
};
```
Expand All @@ -250,7 +250,7 @@ const generateDeny = function (principalId: string, resource: string, context?:

<AppInfoForm askForWebsiteDomain>

- In your API Gateway, create the resources and methods you require, enabling CORS if necessary (see [step 4](./api-gateway-config) for details)
- In your API Gateway, create the resources and methods you require, enabling CORS if necessary (see [setup api gateway](./setup-api-gateway) for details)
- Select each Method you want to enable the Authorizer on and configure it to use the new Authorizer
- Click on "Method Request"
- Edit the "Authorization" field in Settings and set it to the one we just created.
Expand Down
Loading

0 comments on commit a0289dd

Please sign in to comment.