diff --git a/.gitignore b/.gitignore index 74821944..2698720d 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,25 @@ Thumbs.db *.vi *.zip *~ + +#amplify-do-not-edit-begin +amplify/\#current-cloud-backend +amplify/.config/local-* +amplify/logs +amplify/mock-data +amplify/mock-api-resources +amplify/backend/amplify-meta.json +amplify/backend/.temp +build/ +dist/ +node_modules/ +aws-exports.js +awsconfiguration.json +amplifyconfiguration.json +amplifyconfiguration.dart +amplify-build-config.json +amplify-gradle-config.json +amplifytools.xcconfig +.secret-* +**.sample +#amplify-do-not-edit-end diff --git a/amplify/.config/project-config.json b/amplify/.config/project-config.json new file mode 100644 index 00000000..21b7ad03 --- /dev/null +++ b/amplify/.config/project-config.json @@ -0,0 +1,17 @@ +{ + "projectName": "coreuifreevueadminte", + "version": "3.1", + "frontend": "javascript", + "javascript": { + "framework": "vue", + "config": { + "SourceDir": "src", + "DistributionDir": "dist", + "BuildCommand": "npm run-script build", + "StartCommand": "npm run-script serve" + } + }, + "providers": [ + "awscloudformation" + ] +} \ No newline at end of file diff --git a/amplify/README.md b/amplify/README.md new file mode 100644 index 00000000..46165a9c --- /dev/null +++ b/amplify/README.md @@ -0,0 +1,8 @@ +# Getting Started with Amplify CLI +This directory was generated by [Amplify CLI](https://docs.amplify.aws/cli). + +Helpful resources: +- Amplify documentation: https://docs.amplify.aws. +- Amplify CLI documentation: https://docs.amplify.aws/cli. +- More details on this folder & generated files: https://docs.amplify.aws/cli/reference/files. +- Join Amplify's community: https://amplify.aws/community/. diff --git a/amplify/backend/api/ab3examapi/cli-inputs.json b/amplify/backend/api/ab3examapi/cli-inputs.json new file mode 100644 index 00000000..0b916e1f --- /dev/null +++ b/amplify/backend/api/ab3examapi/cli-inputs.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "paths": { + "/exam": { + "name": "/exam", + "lambdaFunction": "ab3examapi", + "permissions": { + "setting": "open" + } + } + } +} \ No newline at end of file diff --git a/amplify/backend/api/ab3snsapi/cli-inputs.json b/amplify/backend/api/ab3snsapi/cli-inputs.json new file mode 100644 index 00000000..ea9493f6 --- /dev/null +++ b/amplify/backend/api/ab3snsapi/cli-inputs.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "paths": { + "/sns": { + "name": "/sns", + "lambdaFunction": "ab3snsapi", + "permissions": { + "setting": "open" + } + } + } +} \ No newline at end of file diff --git a/amplify/backend/auth/coreuifreevueadmintec6cf2a16/cli-inputs.json b/amplify/backend/auth/coreuifreevueadmintec6cf2a16/cli-inputs.json new file mode 100644 index 00000000..d27f8252 --- /dev/null +++ b/amplify/backend/auth/coreuifreevueadmintec6cf2a16/cli-inputs.json @@ -0,0 +1,45 @@ +{ + "version": "1", + "cognitoConfig": { + "identityPoolName": "coreuifreevueadmintec6cf2a16_identitypool_c6cf2a16", + "allowUnauthenticatedIdentities": false, + "resourceNameTruncated": "coreuic6cf2a16", + "userPoolName": "coreuifreevueadmintec6cf2a16_userpool_c6cf2a16", + "autoVerifiedAttributes": [ + "email" + ], + "mfaConfiguration": "OFF", + "mfaTypes": [ + "SMS Text Message" + ], + "smsAuthenticationMessage": "Your authentication code is {####}", + "smsVerificationMessage": "Your verification code is {####}", + "emailVerificationSubject": "Your verification code", + "emailVerificationMessage": "Your verification code is {####}", + "defaultPasswordPolicy": false, + "passwordPolicyMinLength": 8, + "passwordPolicyCharacters": [], + "requiredAttributes": [ + "email" + ], + "aliasAttributes": [], + "userpoolClientGenerateSecret": false, + "userpoolClientRefreshTokenValidity": 30, + "userpoolClientWriteAttributes": [ + "email" + ], + "userpoolClientReadAttributes": [ + "email" + ], + "userpoolClientLambdaRole": "coreuic6cf2a16_userpoolclient_lambda_role", + "userpoolClientSetAttributes": false, + "sharedId": "c6cf2a16", + "resourceName": "coreuifreevueadmintec6cf2a16", + "authSelections": "identityPoolAndUserPool", + "useDefault": "default", + "userPoolGroupList": [], + "serviceName": "Cognito", + "usernameCaseSensitive": false, + "useEnabledMfas": true + } +} \ No newline at end of file diff --git a/amplify/backend/backend-config.json b/amplify/backend/backend-config.json new file mode 100644 index 00000000..82d10ea4 --- /dev/null +++ b/amplify/backend/backend-config.json @@ -0,0 +1,124 @@ +{ + "api": { + "ab3examapi": { + "dependsOn": [ + { + "attributes": [ + "Name", + "Arn" + ], + "category": "function", + "resourceName": "ab3examapi" + } + ], + "providerPlugin": "awscloudformation", + "service": "API Gateway" + }, + "ab3snsapi": { + "dependsOn": [ + { + "attributes": [ + "Name", + "Arn" + ], + "category": "function", + "resourceName": "ab3snsapi" + } + ], + "providerPlugin": "awscloudformation", + "service": "API Gateway" + } + }, + "auth": { + "coreuifreevueadmintec6cf2a16": { + "customAuth": false, + "dependsOn": [], + "frontendAuthConfig": { + "mfaConfiguration": "OFF", + "mfaTypes": [ + "SMS" + ], + "passwordProtectionSettings": { + "passwordPolicyCharacters": [], + "passwordPolicyMinLength": 8 + }, + "signupAttributes": [ + "EMAIL" + ], + "socialProviders": [], + "usernameAttributes": [], + "verificationMechanisms": [ + "EMAIL" + ] + }, + "providerPlugin": "awscloudformation", + "service": "Cognito" + } + }, + "function": { + "ab3examapi": { + "build": true, + "dependsOn": [ + { + "attributeEnvMap": { + "Arn": "TABLE_ARN", + "Name": "TABLE_NAME" + }, + "attributes": [ + "Name", + "Arn" + ], + "category": "storage", + "resourceName": "ab3dynamodb" + } + ], + "providerPlugin": "awscloudformation", + "service": "Lambda" + }, + "ab3snsapi": { + "build": true, + "providerPlugin": "awscloudformation", + "service": "Lambda" + } + }, + "parameters": { + "AMPLIFY_function_ab3examapi_deploymentBucketName": { + "usedBy": [ + { + "category": "function", + "resourceName": "ab3examapi" + } + ] + }, + "AMPLIFY_function_ab3examapi_s3Key": { + "usedBy": [ + { + "category": "function", + "resourceName": "ab3examapi" + } + ] + }, + "AMPLIFY_function_ab3snsapi_deploymentBucketName": { + "usedBy": [ + { + "category": "function", + "resourceName": "ab3snsapi" + } + ] + }, + "AMPLIFY_function_ab3snsapi_s3Key": { + "usedBy": [ + { + "category": "function", + "resourceName": "ab3snsapi" + } + ] + } + }, + "storage": { + "ab3dynamodb": { + "providerPlugin": "awscloudformation", + "service": "DynamoDB" + } + } +} \ No newline at end of file diff --git a/amplify/backend/function/ab3examapi/ab3examapi-cloudformation-template.json b/amplify/backend/function/ab3examapi/ab3examapi-cloudformation-template.json new file mode 100644 index 00000000..20b21cc0 --- /dev/null +++ b/amplify/backend/function/ab3examapi/ab3examapi-cloudformation-template.json @@ -0,0 +1,238 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.11.1\",\"stackType\":\"function-Lambda\",\"metadata\":{}}", + "Parameters": { + "CloudWatchRule": { + "Type": "String", + "Default": "NONE", + "Description": " Schedule Expression" + }, + "deploymentBucketName": { + "Type": "String" + }, + "env": { + "Type": "String" + }, + "s3Key": { + "Type": "String" + }, + "storageab3dynamodbName": { + "Type": "String", + "Default": "storageab3dynamodbName" + }, + "storageab3dynamodbArn": { + "Type": "String", + "Default": "storageab3dynamodbArn" + } + }, + "Conditions": { + "ShouldNotCreateEnvResources": { + "Fn::Equals": [ + { + "Ref": "env" + }, + "NONE" + ] + } + }, + "Resources": { + "LambdaFunction": { + "Type": "AWS::Lambda::Function", + "Metadata": { + "aws:asset:path": "./src", + "aws:asset:property": "Code" + }, + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "deploymentBucketName" + }, + "S3Key": { + "Ref": "s3Key" + } + }, + "Handler": "index.handler", + "FunctionName": { + "Fn::If": [ + "ShouldNotCreateEnvResources", + "ab3examapi", + { + "Fn::Join": [ + "", + [ + "ab3examapi", + "-", + { + "Ref": "env" + } + ] + ] + } + ] + }, + "Environment": { + "Variables": { + "ENV": { + "Ref": "env" + }, + "REGION": { + "Ref": "AWS::Region" + } + } + }, + "Role": { + "Fn::GetAtt": [ + "LambdaExecutionRole", + "Arn" + ] + }, + "Runtime": "nodejs18.x", + "Layers": [], + "Timeout": 25 + } + }, + "LambdaExecutionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "RoleName": { + "Fn::If": [ + "ShouldNotCreateEnvResources", + "coreuifreevueadminteLambdaRolefa7ce4c8", + { + "Fn::Join": [ + "", + [ + "coreuifreevueadminteLambdaRolefa7ce4c8", + "-", + { + "Ref": "env" + } + ] + ] + } + ] + }, + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + }, + "Action": [ + "sts:AssumeRole" + ] + } + ] + } + } + }, + "lambdaexecutionpolicy": { + "DependsOn": [ + "LambdaExecutionRole" + ], + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyName": "lambda-execution-policy", + "Roles": [ + { + "Ref": "LambdaExecutionRole" + } + ], + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Resource": { + "Fn::Sub": [ + "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", + { + "region": { + "Ref": "AWS::Region" + }, + "account": { + "Ref": "AWS::AccountId" + }, + "lambda": { + "Ref": "LambdaFunction" + } + } + ] + } + }, + { + "Effect": "Allow", + "Action": [ + "dynamodb:DescribeTable", + "dynamodb:GetItem", + "dynamodb:Query", + "dynamodb:Scan", + "dynamodb:PutItem", + "dynamodb:UpdateItem", + "dynamodb:DeleteItem" + ], + "Resource": [ + { + "Ref": "storageab3dynamodbArn" + }, + { + "Fn::Join": [ + "/", + [ + { + "Ref": "storageab3dynamodbArn" + }, + "index/*" + ] + ] + } + ] + } + ] + } + } + } + }, + "Outputs": { + "Name": { + "Value": { + "Ref": "LambdaFunction" + } + }, + "Arn": { + "Value": { + "Fn::GetAtt": [ + "LambdaFunction", + "Arn" + ] + } + }, + "Region": { + "Value": { + "Ref": "AWS::Region" + } + }, + "LambdaExecutionRole": { + "Value": { + "Ref": "LambdaExecutionRole" + } + }, + "LambdaExecutionRoleArn": { + "Value": { + "Fn::GetAtt": [ + "LambdaExecutionRole", + "Arn" + ] + } + } + } +} \ No newline at end of file diff --git a/amplify/backend/function/ab3examapi/amplify.state b/amplify/backend/function/ab3examapi/amplify.state new file mode 100644 index 00000000..2a685b3b --- /dev/null +++ b/amplify/backend/function/ab3examapi/amplify.state @@ -0,0 +1,6 @@ +{ + "pluginId": "amplify-nodejs-function-runtime-provider", + "functionRuntime": "nodejs", + "useLegacyBuild": true, + "defaultEditorFile": "src/app.js" +} \ No newline at end of file diff --git a/amplify/backend/function/ab3examapi/custom-policies.json b/amplify/backend/function/ab3examapi/custom-policies.json new file mode 100644 index 00000000..528c94f2 --- /dev/null +++ b/amplify/backend/function/ab3examapi/custom-policies.json @@ -0,0 +1,6 @@ +[ + { + "Action": [], + "Resource": [] + } +] \ No newline at end of file diff --git a/amplify/backend/function/ab3examapi/function-parameters.json b/amplify/backend/function/ab3examapi/function-parameters.json new file mode 100644 index 00000000..d5078776 --- /dev/null +++ b/amplify/backend/function/ab3examapi/function-parameters.json @@ -0,0 +1,3 @@ +{ + "lambdaLayers": [] +} \ No newline at end of file diff --git a/amplify/backend/function/ab3examapi/src/app.js b/amplify/backend/function/ab3examapi/src/app.js new file mode 100644 index 00000000..cff17913 --- /dev/null +++ b/amplify/backend/function/ab3examapi/src/app.js @@ -0,0 +1,250 @@ +/* +Copyright 2017 - 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at + http://aws.amazon.com/apache2.0/ +or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and limitations under the License. +*/ + + + +const { DynamoDBClient } = require('@aws-sdk/client-dynamodb'); +const { DeleteCommand, DynamoDBDocumentClient, GetCommand, PutCommand, QueryCommand, ScanCommand } = require('@aws-sdk/lib-dynamodb'); +const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware') +const bodyParser = require('body-parser') +const express = require('express') + +const ddbClient = new DynamoDBClient({ region: process.env.TABLE_REGION }); +const ddbDocClient = DynamoDBDocumentClient.from(ddbClient); + +let tableName = "ab3examtable"; +if (process.env.ENV && process.env.ENV !== "NONE") { + tableName = tableName + '-' + process.env.ENV; +} + +const userIdPresent = false; // TODO: update in case is required to use that definition +const partitionKeyName = "id"; +const partitionKeyType = "N"; +const sortKeyName = "subject"; +const sortKeyType = "S"; +const hasSortKey = sortKeyName !== ""; +const path = "/exam"; +const UNAUTH = 'UNAUTH'; +const hashKeyPath = '/:' + partitionKeyName; +const sortKeyPath = hasSortKey ? '/:' + sortKeyName : ''; + +// declare a new express app +const app = express() +app.use(bodyParser.json()) +app.use(awsServerlessExpressMiddleware.eventContext()) + +// Enable CORS for all methods +app.use(function(req, res, next) { + res.header("Access-Control-Allow-Origin", "*") + res.header("Access-Control-Allow-Headers", "*") + next() +}); + +// convert url string param to expected Type +const convertUrlType = (param, type) => { + switch(type) { + case "N": + return Number.parseInt(param); + default: + return param; + } +} + +/************************************ +* HTTP Get method to list objects * +************************************/ + +app.get(path, async function(req, res) { + var params = { + TableName: tableName, + Select: 'ALL_ATTRIBUTES', + }; + + try { + const data = await ddbDocClient.send(new ScanCommand(params)); + res.json(data.Items); + } catch (err) { + res.statusCode = 500; + res.json({error: 'Could not load items: ' + err.message}); + } +}); + +/************************************ + * HTTP Get method to query objects * + ************************************/ + +app.get(path + hashKeyPath, async function(req, res) { + const condition = {} + condition[partitionKeyName] = { + ComparisonOperator: 'EQ' + } + + if (userIdPresent && req.apiGateway) { + condition[partitionKeyName]['AttributeValueList'] = [req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH ]; + } else { + try { + condition[partitionKeyName]['AttributeValueList'] = [ convertUrlType(req.params[partitionKeyName], partitionKeyType) ]; + } catch(err) { + res.statusCode = 500; + res.json({error: 'Wrong column type ' + err}); + } + } + + let queryParams = { + TableName: tableName, + KeyConditions: condition + } + + try { + const data = await ddbDocClient.send(new QueryCommand(queryParams)); + res.json(data.Items); + } catch (err) { + res.statusCode = 500; + res.json({error: 'Could not load items: ' + err.message}); + } +}); + +/***************************************** + * HTTP Get method for get single object * + *****************************************/ + +app.get(path + '/object' + hashKeyPath + sortKeyPath, async function(req, res) { + const params = {}; + if (userIdPresent && req.apiGateway) { + params[partitionKeyName] = req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH; + } else { + params[partitionKeyName] = req.params[partitionKeyName]; + try { + params[partitionKeyName] = convertUrlType(req.params[partitionKeyName], partitionKeyType); + } catch(err) { + res.statusCode = 500; + res.json({error: 'Wrong column type ' + err}); + } + } + if (hasSortKey) { + try { + params[sortKeyName] = convertUrlType(req.params[sortKeyName], sortKeyType); + } catch(err) { + res.statusCode = 500; + res.json({error: 'Wrong column type ' + err}); + } + } + + let getItemParams = { + TableName: tableName, + Key: params + } + + try { + const data = await ddbDocClient.send(new GetCommand(getItemParams)); + if (data.Item) { + res.json(data.Item); + } else { + res.json(data) ; + } + } catch (err) { + res.statusCode = 500; + res.json({error: 'Could not load items: ' + err.message}); + } +}); + + +/************************************ +* HTTP put method for insert object * +*************************************/ + +app.put(path, async function(req, res) { + + if (userIdPresent) { + req.body['userId'] = req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH; + } + + let putItemParams = { + TableName: tableName, + Item: req.body + } + try { + let data = await ddbDocClient.send(new PutCommand(putItemParams)); + res.json({ success: 'put call succeed!', url: req.url, data: data }) + } catch (err) { + res.statusCode = 500; + res.json({ error: err, url: req.url, body: req.body }); + } +}); + +/************************************ +* HTTP post method for insert object * +*************************************/ + +app.post(path, async function(req, res) { + + if (userIdPresent) { + req.body['userId'] = req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH; + } + + let putItemParams = { + TableName: tableName, + Item: req.body + } + try { + let data = await ddbDocClient.send(new PutCommand(putItemParams)); + res.json({ success: 'post call succeed!', url: req.url, data: data }) + } catch (err) { + res.statusCode = 500; + res.json({ error: err, url: req.url, body: req.body }); + } +}); + +/************************************** +* HTTP remove method to delete object * +***************************************/ + +app.delete(path + '/object' + hashKeyPath + sortKeyPath, async function(req, res) { + const params = {}; + if (userIdPresent && req.apiGateway) { + params[partitionKeyName] = req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH; + } else { + params[partitionKeyName] = req.params[partitionKeyName]; + try { + params[partitionKeyName] = convertUrlType(req.params[partitionKeyName], partitionKeyType); + } catch(err) { + res.statusCode = 500; + res.json({error: 'Wrong column type ' + err}); + } + } + if (hasSortKey) { + try { + params[sortKeyName] = convertUrlType(req.params[sortKeyName], sortKeyType); + } catch(err) { + res.statusCode = 500; + res.json({error: 'Wrong column type ' + err}); + } + } + + let removeItemParams = { + TableName: tableName, + Key: params + } + + try { + let data = await ddbDocClient.send(new DeleteCommand(removeItemParams)); + res.json({url: req.url, data: data}); + } catch (err) { + res.statusCode = 500; + res.json({error: err, url: req.url}); + } +}); + +app.listen(3000, function() { + console.log("App started") +}); + +// Export the app object. When executing the application local this does nothing. However, +// to port it to AWS Lambda we will create a wrapper around that will load the app from +// this file +module.exports = app diff --git a/amplify/backend/function/ab3examapi/src/event.json b/amplify/backend/function/ab3examapi/src/event.json new file mode 100644 index 00000000..77c9a116 --- /dev/null +++ b/amplify/backend/function/ab3examapi/src/event.json @@ -0,0 +1,11 @@ +{ + "httpMethod": "POST", + "path": "/item", + "queryStringParameters": { + "limit": "10" + }, + "headers": { + "Content-Type": "application/json" + }, + "body": "{\"msg\":\"Hello from the event.json body\"}" +} diff --git a/amplify/backend/function/ab3examapi/src/index.js b/amplify/backend/function/ab3examapi/src/index.js new file mode 100644 index 00000000..832a7f6e --- /dev/null +++ b/amplify/backend/function/ab3examapi/src/index.js @@ -0,0 +1,15 @@ +const awsServerlessExpress = require('aws-serverless-express'); +const app = require('./app'); + +/** + * @type {import('http').Server} + */ +const server = awsServerlessExpress.createServer(app); + +/** + * @type {import('@types/aws-lambda').APIGatewayProxyHandler} + */ +exports.handler = (event, context) => { + console.log(`EVENT: ${JSON.stringify(event)}`); + return awsServerlessExpress.proxy(server, event, context, 'PROMISE').promise; +}; diff --git a/amplify/backend/function/ab3examapi/src/package.json b/amplify/backend/function/ab3examapi/src/package.json new file mode 100644 index 00000000..a96a7097 --- /dev/null +++ b/amplify/backend/function/ab3examapi/src/package.json @@ -0,0 +1,19 @@ +{ + "name": "ab3examapi", + "version": "1.0.0", + "description": "Lambda function generated by Amplify", + "main": "index.js", + "license": "Apache-2.0", + "dependencies": { + "aws-serverless-express": "^3.3.5", + "body-parser": "^1.19.1", + "express": "^4.17.2" + }, + "devDependencies": { + "@types/aws-lambda": "^8.10.92", + "@aws-sdk/client-dynamodb": "^3.188.0", + "@aws-sdk/lib-dynamodb": "^3.188.0", + "@aws-sdk/smithy-client": "^3.188.0", + "@aws-sdk/types" : "^3.188.0" + } +} diff --git a/amplify/backend/function/ab3snsapi/ab3snsapi-cloudformation-template.json b/amplify/backend/function/ab3snsapi/ab3snsapi-cloudformation-template.json new file mode 100644 index 00000000..60799007 --- /dev/null +++ b/amplify/backend/function/ab3snsapi/ab3snsapi-cloudformation-template.json @@ -0,0 +1,202 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.11.1\",\"stackType\":\"function-Lambda\",\"metadata\":{}}", + "Parameters": { + "CloudWatchRule": { + "Type": "String", + "Default": "NONE", + "Description": " Schedule Expression" + }, + "deploymentBucketName": { + "Type": "String" + }, + "env": { + "Type": "String" + }, + "s3Key": { + "Type": "String" + } + }, + "Conditions": { + "ShouldNotCreateEnvResources": { + "Fn::Equals": [ + { + "Ref": "env" + }, + "NONE" + ] + } + }, + "Resources": { + "LambdaFunction": { + "Type": "AWS::Lambda::Function", + "Metadata": { + "aws:asset:path": "./src", + "aws:asset:property": "Code" + }, + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "deploymentBucketName" + }, + "S3Key": { + "Ref": "s3Key" + } + }, + "Handler": "index.handler", + "FunctionName": { + "Fn::If": [ + "ShouldNotCreateEnvResources", + "ab3snsapi", + { + "Fn::Join": [ + "", + [ + "ab3snsapi", + "-", + { + "Ref": "env" + } + ] + ] + } + ] + }, + "Environment": { + "Variables": { + "ENV": { + "Ref": "env" + }, + "REGION": { + "Ref": "AWS::Region" + } + } + }, + "Role": { + "Fn::GetAtt": [ + "LambdaExecutionRole", + "Arn" + ] + }, + "Runtime": "nodejs18.x", + "Layers": [], + "Timeout": 25 + } + }, + "LambdaExecutionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "RoleName": { + "Fn::If": [ + "ShouldNotCreateEnvResources", + "coreuifreevueadminteLambdaRole22126aa1", + { + "Fn::Join": [ + "", + [ + "coreuifreevueadminteLambdaRole22126aa1", + "-", + { + "Ref": "env" + } + ] + ] + } + ] + }, + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + }, + "Action": [ + "sts:AssumeRole" + ] + } + ] + } + } + }, + "lambdaexecutionpolicy": { + "DependsOn": [ + "LambdaExecutionRole" + ], + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyName": "lambda-execution-policy", + "Roles": [ + { + "Ref": "LambdaExecutionRole" + } + ], + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Resource": { + "Fn::Sub": [ + "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", + { + "region": { + "Ref": "AWS::Region" + }, + "account": { + "Ref": "AWS::AccountId" + }, + "lambda": { + "Ref": "LambdaFunction" + } + } + ] + } + } + ] + } + } + } + }, + "Outputs": { + "Name": { + "Value": { + "Ref": "LambdaFunction" + } + }, + "Arn": { + "Value": { + "Fn::GetAtt": [ + "LambdaFunction", + "Arn" + ] + } + }, + "Region": { + "Value": { + "Ref": "AWS::Region" + } + }, + "LambdaExecutionRole": { + "Value": { + "Ref": "LambdaExecutionRole" + } + }, + "LambdaExecutionRoleArn": { + "Value": { + "Fn::GetAtt": [ + "LambdaExecutionRole", + "Arn" + ] + } + } + } +} \ No newline at end of file diff --git a/amplify/backend/function/ab3snsapi/amplify.state b/amplify/backend/function/ab3snsapi/amplify.state new file mode 100644 index 00000000..0c3efe04 --- /dev/null +++ b/amplify/backend/function/ab3snsapi/amplify.state @@ -0,0 +1,6 @@ +{ + "pluginId": "amplify-nodejs-function-runtime-provider", + "functionRuntime": "nodejs", + "useLegacyBuild": true, + "defaultEditorFile": "src/index.js" +} \ No newline at end of file diff --git a/amplify/backend/function/ab3snsapi/custom-policies.json b/amplify/backend/function/ab3snsapi/custom-policies.json new file mode 100644 index 00000000..528c94f2 --- /dev/null +++ b/amplify/backend/function/ab3snsapi/custom-policies.json @@ -0,0 +1,6 @@ +[ + { + "Action": [], + "Resource": [] + } +] \ No newline at end of file diff --git a/amplify/backend/function/ab3snsapi/function-parameters.json b/amplify/backend/function/ab3snsapi/function-parameters.json new file mode 100644 index 00000000..d5078776 --- /dev/null +++ b/amplify/backend/function/ab3snsapi/function-parameters.json @@ -0,0 +1,3 @@ +{ + "lambdaLayers": [] +} \ No newline at end of file diff --git a/amplify/backend/function/ab3snsapi/src/event.json b/amplify/backend/function/ab3snsapi/src/event.json new file mode 100644 index 00000000..fd2722e8 --- /dev/null +++ b/amplify/backend/function/ab3snsapi/src/event.json @@ -0,0 +1,5 @@ +{ + "key1": "value1", + "key2": "value2", + "key3": "value3" +} diff --git a/amplify/backend/function/ab3snsapi/src/index.js b/amplify/backend/function/ab3snsapi/src/index.js new file mode 100644 index 00000000..adeda18c --- /dev/null +++ b/amplify/backend/function/ab3snsapi/src/index.js @@ -0,0 +1,48 @@ +const AWS = require('aws-sdk'); + +/** + * @type {import('@types/aws-lambda').APIGatewayProxyHandler} + */ +exports.handler = async (event) => { + console.log(`EVENT: ${JSON.stringify(event)}`); + + try { + // Create an SNS client + const sns = new AWS.SNS(); + + // Define the SNS topic ARN + const topicArn = 'arn:aws:sns:ap-southeast-1:590183969838:RequestRetake'; + + // Define the message to be published + const message = 'AK from Class A request to retake English Paper'; + + // Publish the message to the SNS topic + const publishParams = { + Message: message, + TopicArn: topicArn + }; + + await sns.publish(publishParams).promise(); + + console.log('Message published to SNS topic successfully'); + + return { + statusCode: 200, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "*" + }, + body: JSON.stringify('Message published to SNS topic'), + }; + } catch (error) { + console.error('Error publishing message to SNS topic:', error); + return { + statusCode: 500, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "*" + }, + body: JSON.stringify('Error publishing message to SNS topic'), + }; + } +}; diff --git a/amplify/backend/function/ab3snsapi/src/package.json b/amplify/backend/function/ab3snsapi/src/package.json new file mode 100644 index 00000000..6791d79a --- /dev/null +++ b/amplify/backend/function/ab3snsapi/src/package.json @@ -0,0 +1,10 @@ +{ + "name": "ab3snsapi", + "version": "2.0.0", + "description": "Lambda function generated by Amplify", + "main": "index.js", + "license": "Apache-2.0", + "devDependencies": { + "@types/aws-lambda": "^8.10.92" + } +} diff --git a/amplify/backend/storage/ab3dynamodb/cli-inputs.json b/amplify/backend/storage/ab3dynamodb/cli-inputs.json new file mode 100644 index 00000000..ceb7c82b --- /dev/null +++ b/amplify/backend/storage/ab3dynamodb/cli-inputs.json @@ -0,0 +1,14 @@ +{ + "resourceName": "ab3dynamodb", + "tableName": "ab3examtable", + "partitionKey": { + "fieldName": "id", + "fieldType": "number" + }, + "sortKey": { + "fieldName": "subject", + "fieldType": "string" + }, + "gsi": [], + "triggerFunctions": [] +} \ No newline at end of file diff --git a/amplify/backend/tags.json b/amplify/backend/tags.json new file mode 100644 index 00000000..b9321d71 --- /dev/null +++ b/amplify/backend/tags.json @@ -0,0 +1,10 @@ +[ + { + "Key": "user:Stack", + "Value": "{project-env}" + }, + { + "Key": "user:Application", + "Value": "{project-name}" + } +] \ No newline at end of file diff --git a/amplify/backend/types/amplify-dependent-resources-ref.d.ts b/amplify/backend/types/amplify-dependent-resources-ref.d.ts new file mode 100644 index 00000000..c949297f --- /dev/null +++ b/amplify/backend/types/amplify-dependent-resources-ref.d.ts @@ -0,0 +1,53 @@ +export type AmplifyDependentResourcesAttributes = { + "api": { + "ab3examapi": { + "ApiId": "string", + "ApiName": "string", + "RootUrl": "string" + }, + "ab3snsapi": { + "ApiId": "string", + "ApiName": "string", + "RootUrl": "string" + } + }, + "auth": { + "coreuifreevueadmintec6cf2a16": { + "AppClientID": "string", + "AppClientIDWeb": "string", + "IdentityPoolId": "string", + "IdentityPoolName": "string", + "UserPoolArn": "string", + "UserPoolId": "string", + "UserPoolName": "string" + } + }, + "function": { + "ab3examapi": { + "Arn": "string", + "LambdaExecutionRole": "string", + "LambdaExecutionRoleArn": "string", + "Name": "string", + "Region": "string" + }, + "ab3snsapi": { + "Arn": "string", + "LambdaExecutionRole": "string", + "LambdaExecutionRoleArn": "string", + "Name": "string", + "Region": "string" + } + }, + "storage": { + "ab3dynamodb": { + "Arn": "string", + "Name": "string", + "PartitionKeyName": "string", + "PartitionKeyType": "string", + "Region": "string", + "SortKeyName": "string", + "SortKeyType": "string", + "StreamArn": "string" + } + } +} \ No newline at end of file diff --git a/amplify/cli.json b/amplify/cli.json new file mode 100644 index 00000000..1058d7b0 --- /dev/null +++ b/amplify/cli.json @@ -0,0 +1,63 @@ +{ + "features": { + "graphqltransformer": { + "addmissingownerfields": true, + "improvepluralization": false, + "validatetypenamereservedwords": true, + "useexperimentalpipelinedtransformer": true, + "enableiterativegsiupdates": true, + "secondarykeyasgsi": true, + "skipoverridemutationinputtypes": true, + "transformerversion": 2, + "suppressschemamigrationprompt": true, + "securityenhancementnotification": false, + "showfieldauthnotification": false, + "usesubusernamefordefaultidentityclaim": true, + "usefieldnameforprimarykeyconnectionfield": false, + "enableautoindexquerynames": true, + "respectprimarykeyattributesonconnectionfield": true, + "shoulddeepmergedirectiveconfigdefaults": false, + "populateownerfieldforstaticgroupauth": true + }, + "frontend-ios": { + "enablexcodeintegration": true + }, + "auth": { + "enablecaseinsensitivity": true, + "useinclusiveterminology": true, + "breakcirculardependency": true, + "forcealiasattributes": false, + "useenabledmfas": true + }, + "codegen": { + "useappsyncmodelgenplugin": true, + "usedocsgeneratorplugin": true, + "usetypesgeneratorplugin": true, + "cleangeneratedmodelsdirectory": true, + "retaincasestyle": true, + "addtimestampfields": true, + "handlelistnullabilitytransparently": true, + "emitauthprovider": true, + "generateindexrules": true, + "enabledartnullsafety": true, + "generatemodelsforlazyloadandcustomselectionset": false + }, + "appsync": { + "generategraphqlpermissions": true + }, + "latestregionsupport": { + "pinpoint": 1, + "translate": 1, + "transcribe": 1, + "rekognition": 1, + "textract": 1, + "comprehend": 1 + }, + "project": { + "overrides": true + } + }, + "debug": { + "shareProjectConfig": false + } +} \ No newline at end of file diff --git a/amplify/hooks/README.md b/amplify/hooks/README.md new file mode 100644 index 00000000..8fb601ea --- /dev/null +++ b/amplify/hooks/README.md @@ -0,0 +1,7 @@ +# Command Hooks + +Command hooks can be used to run custom scripts upon Amplify CLI lifecycle events like pre-push, post-add-function, etc. + +To get started, add your script files based on the expected naming convention in this directory. + +Learn more about the script file naming convention, hook parameters, third party dependencies, and advanced configurations at https://docs.amplify.aws/cli/usage/command-hooks diff --git a/amplify/team-provider-info.json b/amplify/team-provider-info.json new file mode 100644 index 00000000..54e0ea34 --- /dev/null +++ b/amplify/team-provider-info.json @@ -0,0 +1,37 @@ +{ + "dev": { + "awscloudformation": { + "AuthRoleName": "amplify-coreuifreevueadminte-dev-3084a-authRole", + "UnauthRoleArn": "arn:aws:iam::590183969838:role/amplify-coreuifreevueadminte-dev-3084a-unauthRole", + "AuthRoleArn": "arn:aws:iam::590183969838:role/amplify-coreuifreevueadminte-dev-3084a-authRole", + "Region": "ap-southeast-1", + "DeploymentBucketName": "amplify-coreuifreevueadminte-dev-3084a-deployment", + "UnauthRoleName": "amplify-coreuifreevueadminte-dev-3084a-unauthRole", + "StackName": "amplify-coreuifreevueadminte-dev-3084a", + "StackId": "arn:aws:cloudformation:ap-southeast-1:590183969838:stack/amplify-coreuifreevueadminte-dev-3084a/50c48fd0-0c79-11ef-b93d-06c8b6197539", + "AmplifyAppId": "d3m5s31qhs79o0" + }, + "categories": { + "auth": { + "coreuifreevueadmintec6cf2a16": {} + }, + "function": { + "ab3examapi": { + "deploymentBucketName": "amplify-coreuifreevueadminte-dev-3084a-deployment", + "s3Key": "amplify-builds/ab3examapi-4575667447613558666e-build.zip" + }, + "ab3snsapi": { + "deploymentBucketName": "amplify-coreuifreevueadminte-dev-3084a-deployment", + "s3Key": "amplify-builds/ab3snsapi-49597163366773355466-build.zip" + } + }, + "storage": { + "ab3dynamodb": {} + }, + "api": { + "ab3examapi": {}, + "ab3snsapi": {} + } + } + } +} \ No newline at end of file diff --git a/index.html b/index.html index 1c4aae12..df9d2882 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@ -
Loading exam results...
+Loading exam results list...
+