Jon Holman
06/02/2022, 12:40 AMKenny
06/02/2022, 2:00 AMexport function AuthStack({ stack, app }) {
const { bucket } = use(StorageStack);
const { api } = use(ApiStack);
const auth = new Auth(stack, "Auth", {
login: ["email"],
identityPoolFederation: {
google: {
clientId:
"<http://1097663769791-MYGOOGLECLIENTID.apps.googleusercontent.com|1097663769791-MYGOOGLECLIENTID.apps.googleusercontent.com>",
},
},
});
auth.attachPermissionsForAuthUsers([
api,
new iam.PolicyStatement({
actions: ["s3:*"],
effect: iam.Effect.ALLOW,
resources: [
bucket.bucketArn + "/private/${<http://cognito-identity.amazonaws.com:sub|cognito-identity.amazonaws.com:sub>}/*",
],
}),
]);
stack.addOutputs({
Region: app.region,
UserPoolId: auth.userPoolId,
IdentityPoolId: auth.cognitoIdentityPoolId,
UserPoolClientId: auth.userPoolClientId,
});
return { auth };
}
I found one for Facebook on github https://github.com/AnomalyInnovations/serverless-stack-demo-fb-login-client But is it the same for google?ray
06/02/2022, 2:55 AMrawbody
?Francis Menguito
06/02/2022, 8:18 AMAuth
class?Neil Balcombe
06/02/2022, 10:20 AMRobb Winkle
06/02/2022, 1:19 PMexport default async function main(app: App) {
await stack1Init();
await stack2Init();
app.stack(stack1)
.stack(stack2)
.stack(stack3)
}
I could also be doing something that wasn't intended and I'm looking for feedback on that as well. I'm looking for a better way to do this.Arpad
06/02/2022, 1:36 PMto
email is verified, however I am out of sandbox (and tested sending from the console)...
I'm trying with the CLI atm and getting this... I'm sending from a profile that is in the dev account, same regions everywhere
AWS_REGION=eu-west-1 aws ses send-email --to "my_email" --from "noreply@my-domain" --subject "test iam" --text "hey there" --source-arn "arn:aws:ses:eu-west-1:123456789012:identity/my-domain"
An error occurred (MessageRejected) when calling the SendEmail operation: Email address is not verified. The following identities failed the check in region EU-WEST-1: my_email
Austin
06/02/2022, 1:58 PMdotnet
executable location that SST uses for running C# functions? I have an M1 Macbook and it requires some trickery to install .NET Core 3.1 involving putting it in a non-standard location from newer dotnet runtimes.
I need to run some 3.1 Lambda functions within an SST project, but it can’t find the runtime. Is there a way to configure this executable location?Tobias T
06/02/2022, 4:00 PMMike Holloway
06/02/2022, 7:15 PMKenny
06/02/2022, 7:59 PMexport const main = handler(async (event) => {
const data = JSON.parse(event.body);
const params = {
TableName: process.env.TABLE_NAME,
Item: {
userId: event.requestContext.authorizer.jwt.claims.sub,
noteId: uuid.v1(),
content: data.content,
attachment: data.attachment,
createdAt: Date.now(),
},
};
await dynamoDB.put(params);
return params.Item;
});
I am setting the sub event*.*_requestContext_*.*_authorizer_*.*_jwt_*.*_claims_*.*_sub_
as the userId. When making this request I get a 401 Error saying I am unauthorized. But when I make a get request I don't get an error. function for the get request "get a list of notes"
export const main = handler(async (event) => {
const params = {
TableName: process.env.TABLE_NAME,
KeyConditionExpression: "userId = :userId",
ExpressionAttributeValues: {
":userId": event.requestContext.authorizer.jwt.claims.sub,
},
};
const result = await dynamoDB.query(params);
return result.Items;
});
and this is my full API and AUTH stack
import * as iam from "aws-cdk-lib/aws-iam";
import * as cognito from "aws-cdk-lib/aws-cognito";
import * as apigAuthorizers from "@aws-cdk/aws-apigatewayv2-authorizers-alpha";
import { Auth, Api, use } from "@serverless-stack/resources";
import { StorageStack } from "./StorageStack";
export function AuthApiStack({ stack, app }) {
const { bucket } = use(StorageStack);
const { table } = use(StorageStack); //This new ApiStack references the table resource from the StorageStack that we created previously.
const auth = new Auth(stack, "Auth", {
login: ["email"],
cdk: {
userPoolClient: {
supportedIdentityProviders: [
cognito.UserPoolClientIdentityProvider.GOOGLE,
cognito.UserPoolClientIdentityProvider.COGNITO,
],
oAuth: {
callbackUrls: [
app.stage === "prod"
? "prodDomainNameUrl"
: "<http://localhost:3000>",
],
logoutUrls: [
app.stage === "prod"
? "prodDomainNameUrl"
: "<http://localhost:3000>",
],
},
},
},
});
if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_CLIENT_SECRET)
throw new Error("Please set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET");
// Create a Google OAuth provider
const googleProvider = new cognito.UserPoolIdentityProviderGoogle(
stack,
"Google",
{
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
userPool: auth.cdk.userPool,
scopes: ["profile", "email", "openid"],
attributeMapping: {
email: cognito.ProviderAttribute.GOOGLE_EMAIL,
givenName: cognito.ProviderAttribute.GOOGLE_GIVEN_NAME,
familyName: cognito.ProviderAttribute.GOOGLE_FAMILY_NAME,
profilePicture: cognito.ProviderAttribute.GOOGLE_PICTURE,
},
}
);
// Create a Facebook OAuth provider
// attach the created providers to our userpool
auth.cdk.userPoolClient.node.addDependency(googleProvider);
const domain = auth.cdk.userPool.addDomain("AuthDomain", {
cognitoDomain: {
domainPrefix: `${app.stage}-notes-auth-domain`,
},
});
const api = new Api(stack, "Api", {
// defaults: {
// authorizer: "iam",
// function: {
// permissions: [table], //We are giving our API permission to access our DynamoDB table
// environment: {
// TABLE_NAME: table.tableName, //We'll need this to query our table.
// STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
// },
// },
// },
authorizers: {
userPool: {
type: "user_pool",
cdk: {
authorizer: new apigAuthorizers.HttpUserPoolAuthorizer(
"Authorizer",
auth.cdk.userPool,
{
userPoolClients: [auth.cdk.userPoolClient],
}
),
},
},
},
defaults: {
authorizer: "userPool",
function: {
permissions: [table], //We are giving our API permission to access our DynamoDB table
environment: {
TABLE_NAME: table.tableName, //We'll need this to query our table.
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
},
},
},
routes: {
"POST /notes": "functions/create.main",
"GET /notes/{id}": "functions/get.main",
"GET /notes": "functions/list.main",
"PUT /notes/{id}": "functions/update.main",
"DELETE /notes/{id}": "functions/delete.main",
"POST /billing": "functions/billing.main",
},
});
auth.attachPermissionsForAuthUsers([
api,
new iam.PolicyStatement({
actions: ["s3:*"],
effect: iam.Effect.ALLOW,
resources: [
bucket.bucketArn + "/private/${<http://cognito-identity.amazonaws.com:sub|cognito-identity.amazonaws.com:sub>}/*",
],
}),
]);
stack.addOutputs({
ApiEndpoint: api.url,
AuthDomain: domain.domainName,
Region: app.region,
UserPoolId: auth.userPoolId,
IdentityPoolId: auth.cognitoIdentityPoolId,
UserPoolClientId: auth.userPoolClientId,
});
return { auth, api, domain };
}
I am sending this request payload {content: "jhgghj", attachment: null}
from my frontend React to the backend, so I first thought it could be denying access to s3 but clearly I am setting it using iam.PolicyStatement and auth.attachPermissionsForAuthUsers
Viswa
06/02/2022, 8:34 PMKenny
06/02/2022, 10:23 PMdev-notes-StorageStack: dev-notes-Notes already exists in stack arn:aws:cloudformation:us-east-1:168458715623:stack/dev-notes-storage/8c33eb70-33db-11ec-8990-0e40bd8a36fb
How do I remove or overwrite it?Tony J
06/02/2022, 11:56 PMSakar
06/03/2022, 5:17 AMEdoardo
06/03/2022, 2:30 PMScript
inside my db stack to run a migration when the construct is deployed.
When I deploy or remove the stack using sst start
/ sst remove
it takes too much time. For example when I run a remove, CloudFormation takes about 40 minutes to switch from the status MigrationScriptonCreateFunction DELETE_IN_PROGRESS
to the MigrationScriptonCreateFunction DELETE_COMPLETE
. This seems to happen only with Lambda functions managed by Script
, other Lambdas delete smoothly.Patrik Ståhl
06/03/2022, 6:50 PMUsing stage: dev
Preparing your SST app
=======================
Deploying debug stack
=======================
/Users/foo/Development/app/node_modules/@serverless-stack/cli/node_modules/aws-sdk/lib/shared-ini/ini-loader.js:8
Object.keys(content).forEach(function(profileName) {
^
TypeError: Cannot redefine property: foobar-prod
at Function.defineProperty (<anonymous>)
at /Users/foo/Development/app/node_modules/@serverless-stack/cli/node_modules/aws-sdk/lib/shared-ini/ini-loader.js:11:14
at Array.forEach (<anonymous>)
at IniLoader2.parseFile (/Users/foo/Development/app/node_modules/@serverless-stack/cli/node_modules/aws-sdk/lib/shared-ini/ini-loader.js:8:26)
at IniLoader2.loadFrom (/Users/foo/Development/app/node_modules/@serverless-stack/cli/node_modules/aws-sdk/lib/shared-ini/ini-loader.js:56:30)
at getRegion (/Users/foo/Development/app/node_modules/@serverless-stack/cli/node_modules/aws-sdk/lib/node_loader.js:118:32)
at Config.region (/Users/foo/Development/app/node_modules/@serverless-stack/cli/node_modules/aws-sdk/lib/node_loader.js:173:18)
at Config.set (/Users/foo/Development/app/node_modules/@serverless-stack/cli/node_modules/aws-sdk/lib/config.js:524:39)
at Config.<anonymous> (/Users/foo/Development/app/node_modules/@serverless-stack/cli/node_modules/aws-sdk/lib/config.js:359:12)
at Config.each (/Users/foo/Development/app/node_modules/@serverless-stack/cli/node_modules/aws-sdk/lib/util.js:512:32)
Kenny
06/03/2022, 7:31 PM@aws-cdk/aws-apigatewayv2-alpha
I get this error:
✘ [ERROR] Could not resolve "@aws-cdk/aws-apigatewayv2-authorizers-alpha"
stacks/AuthApiStack.js:3:33:
3 │ import * as apigAuthorizers from "@aws-cdk/aws-apigatewayv2-authorizers-alpha";
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can mark the path "@aws-cdk/aws-apigatewayv2-authorizers-alpha" as external to exclude it from
the bundle, which will remove this error.
Build failed with 1 error:
stacks/AuthApiStack.js:3:33: ERROR: Could not resolve "@aws-cdk/aws-apigatewayv2-authorizers-alpha"
eventhough I ran npm install aws-cdk@2.24.0 --save-exact
or npm install aws-cdk
Kristian Lake
06/03/2022, 9:11 PMKevin Grimm
06/04/2022, 4:38 AMnpx sst build
error with a Next/Tailwind starter blog for 3 nights worth of debugging and currently facing a TypeError
. I've been testing different packages, package versions, config files etc but haven't figured out how to crack this one yet
> Build error occurred
TypeError: Cannot read properties of undefined (reading '1')
at isFileType (node:fs:208:19)
at Object.readFileSync (node:fs:456:16)
at /path/to/files/frontend/.next/serverless/chunks/669.js:101784:19
at Array.map (<anonymous>)
at /path/to/files/frontend/.next/serverless/chunks/669.js:101783:30
at Object.35240 (/path/to/files/frontend/.next/serverless/chunks/669.js:101788:2)
at __webpack_require__ (/path/to/files/frontend/.next/serverless/webpack-runtime.js:25:43)
at Object.19625 (/path/to/files/frontend/.next/serverless/chunks/669.js:228937:18)
at __webpack_require__ (/path/to/files/frontend/.next/serverless/webpack-runtime.js:25:43)
at Object.90809 (/path/to/files/frontend/.next/serverless/chunks/332.js:229:28) {
type: 'TypeError'
}
What's odd is that npm run build
runs in the frontend
directory; it's just when trying to execute via sst
where there's an issue... at this point I still can't say for certain that this is an SST issue, but I've scoured multiple threads/questions/issues to no avail. I'm also inexperienced with webpack which is being used in the starter (https://github.com/timlrx/tailwind-nextjs-starter-blog)
Worst case scenario I am going to spin up a new Next frontend and incrementally add in pages/components while validating the build works via npx sst build
. I have a separate SST app that's working with a Next frontend though that one has far fewer bells and whistles (which I'm suspecting is a potential issue besides my lack of familiarity w/ compiling)Ashishkumar Pandey
06/04/2022, 9:38 AM"validator": "git+<https://github.com/ashishpandey001/validator.js#main>"
to my package.json. Unfortunately, I’m unable to import and use this lib in this way. Any ideas why and how could I approach solving this?Shubham Sinha
06/04/2022, 12:05 PM{
"errorMessage": "operation error Cognito Identity Provider: InitiateAuth, https response error StatusCode: 400, RequestID: 1ff27bbe-fce8-4c78-8774-986c5a133099, InvalidParameterException: USER_PASSWORD_AUTH flow not enabled for this client",
"errorType": "OperationError"
}
const auth = new Auth(stack, "Auth", {
login: ["email"],
});
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"<http://github.com/aws/aws-lambda-go/events|github.com/aws/aws-lambda-go/events>"
"<http://github.com/aws/aws-lambda-go/lambda|github.com/aws/aws-lambda-go/lambda>"
"<http://github.com/aws/aws-sdk-go-v2/aws|github.com/aws/aws-sdk-go-v2/aws>"
"<http://github.com/aws/aws-sdk-go-v2/config|github.com/aws/aws-sdk-go-v2/config>"
cognito "<http://github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider|github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider>"
"<http://github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider/types|github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider/types>"
)
type User struct {
Email string `json:"email" validate:"required"`
Password string `json:"password" validate:"required"`
}
func Handler(request events.APIGatewayV2HTTPRequest) (events.APIGatewayProxyResponse, error) {
var userInput User
ApiResponse := events.APIGatewayProxyResponse{}
err := json.Unmarshal([]byte(request.Body), &userInput)
if err != nil {
body := "Error: Invalid JSON payload ||| " + fmt.Sprint(err) + " Body Obtained" + "||||" + request.Body
ApiResponse = events.APIGatewayProxyResponse{Body: body, StatusCode: 500, Headers: map[string]string{"Content-Type": "application/json"}}
return ApiResponse, err
} else {
cfg, err := config.LoadDefaultConfig(context.TODO(), func(o *config.LoadOptions) error {
o.Region = "ap-south-1"
return nil
})
if err != nil {
panic(err)
}
cognitoClient := cognito.NewFromConfig(cfg)
user := &cognito.InitiateAuthInput{
ClientId: aws.String(os.Getenv("cognitoClientId")),
AuthFlow: "USER_PASSWORD_AUTH",
AuthParameters: map[string]string{
"USERNAME": userInput.Email,
"PASSWORD": userInput.Password,
},
}
result, err := cognitoClient.InitiateAuth(context.TODO(), user)
if err != nil {
body := "Error: Invalid JSON payload ||| " + fmt.Sprint(err) + " Body Obtained" + "||||" + request.Body
ApiResponse = events.APIGatewayProxyResponse{Body: body, StatusCode: 500, Headers: map[string]string{"Content-Type": "application/json"}}
return ApiResponse, err
}
response := struct {
AuthResult *types.AuthenticationResultType
}{
AuthResult: result.AuthenticationResult,
}
body, _ := json.Marshal(response)
ApiResponse = events.APIGatewayProxyResponse{Body: string(body), StatusCode: 200, Headers: map[string]string{"Content-Type": "application/json"}}
}
return ApiResponse, nil
}
func main() {
lambda.Start(Handler)
}
Kristian Lake
06/04/2022, 2:29 PMBruno
06/04/2022, 3:25 PM08581965-f277-4f60-9210-d7f52227e4b7 ERROR TypeError: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined
at new NodeError (internal/errors.js:322:7)
at Function.from (buffer.js:334:9)
at RuntimeClient._post (file:///Users/gr33n/Documents/Dev/JS/prisma/node_modules/@serverless-stack/aws-lambda-ric/lib/RuntimeClient/RuntimeClient.js:133:42)
at RuntimeClient.postInvocationResponse (file:///Users/gr33n/Documents/Dev/JS/prisma/node_modules/@serverless-stack/aws-lambda-ric/lib/RuntimeClient/RuntimeClient.js:48:14)
at complete (file:///Users/gr33n/Documents/Dev/JS/prisma/node_modules/@serverless-stack/aws-lambda-ric/lib/Runtime/CallbackContext.js:41:16)
at done (file:///Users/gr33n/Documents/Dev/JS/prisma/node_modules/@serverless-stack/aws-lambda-ric/lib/Runtime/CallbackContext.js:66:13)
at succeed (file:///Users/gr33n/Documents/Dev/JS/prisma/node_modules/@serverless-stack/aws-lambda-ric/lib/Runtime/CallbackContext.js:70:9)
at file:///Users/gr33n/Documents/Dev/JS/prisma/node_modules/@serverless-stack/aws-lambda-ric/lib/Runtime/CallbackContext.js:112:24
>
I suspect that this is because I made the function endpoint async, is that possible? ThanksRobert Gardner
06/04/2022, 4:20 PM// foo.test.ts
import { create } from './service';
jest.mock('./service');
console.log(create);
// logs [AsyncFunction: create] instead of [Function: mockConstructor]
We are using ts-jest and esbuild-runner. Here is jest.config.js:
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/*.test.(ts|tsx|js)'],
testPathIgnorePatterns: ['node_modules', 'build'],
transform: {
'\\.ts$': 'esbuild-runner/jest',
},
}
There is a jest issue that says you can’t mock modules without using Babel, but doesn’t esbuild-runner/jest handle that?
Mocking modules is so common in jest that I’m surprised this isn’t working. There must be something I’m missing in our setup??Kenny
06/04/2022, 5:39 PMKristian Lake
06/04/2022, 6:05 PMKristian Lake
06/04/2022, 11:52 PMKenny
06/05/2022, 11:05 PMJason S
06/06/2022, 5:30 AM