├── client
├── .env
├── postcss.config.js
├── babel.config.js
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── assets
│ │ └── main.scss
│ ├── postcss.config.js
│ ├── router
│ │ └── index.js
│ ├── main.js
│ ├── store
│ │ └── index.js
│ ├── App.vue
│ └── views
│ │ └── Dashboard.vue
├── package.json
└── README.md
├── assets
├── pat.png
└── client.png
├── templates
├── app
│ ├── linkId
│ │ ├── delete-400-response.json
│ │ ├── put-response-200.json
│ │ ├── delete-request.json
│ │ └── put-request.json
│ ├── post-response-400.json
│ ├── post-response-200.json
│ ├── get-response.json
│ ├── get-request.json
│ └── post-request.json
└── linkiId
│ ├── get-request.json
│ └── get-response.json
├── CODE_OF_CONDUCT.md
├── .gitignore
├── LICENSE
├── CONTRIBUTING.md
├── README.md
├── api.yaml
└── template.yaml
/client/.env:
--------------------------------------------------------------------------------
1 | VUE_APP_NAME=
2 | VUE_APP_API_ROOT=
3 | VUE_APP_AUTH_DOMAIN=
4 | VUE_APP_CLIENT_ID=
--------------------------------------------------------------------------------
/client/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | autoprefixer: {}
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/assets/pat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-api-gateway-url-shortener/HEAD/assets/pat.png
--------------------------------------------------------------------------------
/assets/client.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-api-gateway-url-shortener/HEAD/assets/client.png
--------------------------------------------------------------------------------
/client/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-api-gateway-url-shortener/HEAD/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/src/assets/main.scss:
--------------------------------------------------------------------------------
1 | @import "~bulma/bulma";
2 |
3 | .text-clip{
4 | overflow:hidden;
5 | text-overflow: ellipsis;
6 | white-space: nowrap;
7 | }
--------------------------------------------------------------------------------
/templates/app/linkId/delete-400-response.json:
--------------------------------------------------------------------------------
1 | {
2 | "error": {
3 | "message": "Either you do not have permission to do this operation or a parameter is missing"
4 | }
5 | }
--------------------------------------------------------------------------------
/templates/linkiId/get-request.json:
--------------------------------------------------------------------------------
1 | {
2 | "Key": {
3 | "id": {
4 | "S": "$input.params().path.linkId"
5 | }
6 | },
7 | "TableName": "SlipLink-LinkTable-A2SD9C321JCE"
8 | }
--------------------------------------------------------------------------------
/templates/linkiId/get-response.json:
--------------------------------------------------------------------------------
1 | #set($inputRoot = $input.path('$'))
2 | #if ($inputRoot.toString().contains("Item"))
3 | #set($context.responseOverride.header.Location = $inputRoot.Item.url.S)
4 | #end
--------------------------------------------------------------------------------
/templates/app/post-response-400.json:
--------------------------------------------------------------------------------
1 | #set($inputRoot = $input.path('$'))
2 | #if($inputRoot.toString().contains("ConditionalCheckFailedException"))
3 | #set($context.responseOverride.status = 200)
4 | {"error": true,"message": "URL link already exists"}
5 | #end
--------------------------------------------------------------------------------
/templates/app/post-response-200.json:
--------------------------------------------------------------------------------
1 | #set($inputRoot = $input.path('$'))
2 | {
3 | "id": "$inputRoot.Attributes.id.S",
4 | "url": "$inputRoot.Attributes.url.S",
5 | "timestamp": "$inputRoot.Attributes.timestamp.S",
6 | "owner": "$inputRoot.Attributes.owner.S"
7 | }
--------------------------------------------------------------------------------
/templates/app/linkId/put-response-200.json:
--------------------------------------------------------------------------------
1 | #set($inputRoot = $input.path('$'))
2 | {
3 | "id": "$inputRoot.Attributes.id.S",
4 | "url": "$inputRoot.Attributes.url.S",
5 | "timestamp": "$inputRoot.Attributes.timestamp.S",
6 | "owner": "$inputRoot.Attributes.owner.S"
7 | }
--------------------------------------------------------------------------------
/templates/app/get-response.json:
--------------------------------------------------------------------------------
1 | #set($inputRoot = $input.path('$'))
2 | [
3 | #foreach($elem in $inputRoot.Items) {
4 | "id": "$elem.id.S",
5 | "url": "$elem.url.S",
6 | "timestamp": "$elem.timestamp.S",
7 | "owner": "$elem.owner.S"
8 | }#if ($foreach.hasNext),#end
9 | #end
10 | ]
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4 | opensource-codeofconduct@amazon.com with any additional questions or comments.
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | */**/node_modules
3 | */**/dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 | *.toml
--------------------------------------------------------------------------------
/templates/app/get-request.json:
--------------------------------------------------------------------------------
1 | {
2 | "TableName": "SlipLink-LinkTable-A2SD9C321JCE",
3 | "IndexName": "OwnerIndex",
4 | "KeyConditionExpression": "#n_owner = :v_owner",
5 | "ExpressionAttributeValues": {
6 | ":v_owner": {
7 | "S": "$context.authorizer.claims.email"
8 | }
9 | },
10 | "ExpressionAttributeNames": {
11 | "#n_owner": "owner"
12 | }
13 | }
--------------------------------------------------------------------------------
/templates/app/linkId/delete-request.json:
--------------------------------------------------------------------------------
1 | {
2 | "Key": {
3 | "id": {
4 | "S": "$input.params().path.linkId"
5 | }
6 | },
7 | "TableName": "SlipLink-LinkTable-A2SD9C321JCE",
8 | "ConditionExpression": "#owner = :owner",
9 | "ExpressionAttributeValues": {
10 | ":owner": {
11 | "S": "$context.authorizer.claims.email"
12 | }
13 | },
14 | "ExpressionAttributeNames": {
15 | "#owner": "owner"
16 | }
17 | }
--------------------------------------------------------------------------------
/templates/app/linkId/put-request.json:
--------------------------------------------------------------------------------
1 | {
2 | "TableName": "Shortie",
3 | "Key": {
4 | "id": {
5 | "S": $input.json('$.id') + "_" + $context.authorizer.claims.email
6 | }
7 | },
8 | "ExpressionAttributeNames": {
9 | "#u": "url",
10 | "#owner": "owner",
11 | "#id":"id"
12 | },
13 | "ExpressionAttributeValues": {
14 | ":u": {
15 | "S": $input.json('$.url')
16 | },
17 | ":owner": {
18 | "S": "$context.authorizer.claims.email"
19 | },
20 | ":linkId": {
21 | "S": "$input.params().path.linkId"
22 | }
23 | },
24 | "UpdateExpression": "SET #u = :u",
25 | "ReturnValues": "ALL_NEW",
26 | "ConditionExpression": "#owner = :owner AND #id = :linkId"
27 | }
28 |
--------------------------------------------------------------------------------
/templates/app/post-request.json:
--------------------------------------------------------------------------------
1 | {
2 | "TableName": "SlipLink-LinkTable-A2SD9C321JCE",
3 | "ConditionExpression": "attribute_not_exists(id)",
4 | "Key": {
5 | "id": {
6 | "S": $input.json('$.id') + "_" + $context.authorizer.claims.email
7 | }
8 | },
9 | "ExpressionAttributeNames": {
10 | "#u": "url",
11 | "#o": "owner",
12 | "#ts": "timestamp"
13 | },
14 | "ExpressionAttributeValues": {
15 | ":u": {
16 | "S": $input.json('$.url')
17 | },
18 | ":o": {
19 | "S": "$context.authorizer.claims.email"
20 | },
21 | ":ts": {
22 | "S": "$context.requestTime"
23 | }
24 | },
25 | "UpdateExpression": "SET #u = :u, #o = :o, #ts = :ts",
26 | "ReturnValues": "ALL_NEW"
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/client/src/postcss.config.js:
--------------------------------------------------------------------------------
1 | // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: MIT-0
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this
5 | // software and associated documentation files (the "Software"), to deal in the Software
6 | // without restriction, including without limitation the rights to use, copy, modify,
7 | // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8 | // permit persons to whom the Software is furnished to do so.
9 | //
10 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
11 | // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
12 | // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
13 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
14 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 |
17 | module.exports = {
18 | plugins: {
19 | autoprefixer: {}
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client2",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "axios": "^1.8.2",
12 | "bulma": "^1.0.3",
13 | "core-js": "^3.41.0",
14 | "moment": "^2.30.1",
15 | "vue": "^3.5.13",
16 | "vue-router": "^4.5.0",
17 | "vuex": "^4.1.0"
18 | },
19 | "devDependencies": {
20 | "@vue/cli-plugin-babel": "^5.0.8",
21 | "@vue/cli-plugin-eslint": "^5.0.8",
22 | "@vue/cli-plugin-router": "^5.0.8",
23 | "@vue/cli-plugin-vuex": "^5.0.8",
24 | "@vue/cli-service": "^5.0.8",
25 | "babel-eslint": "^10.1.0",
26 | "eslint": "9.22.0",
27 | "eslint-plugin-vue": "^10.0.0",
28 | "sass": "^1.85.1",
29 | "sass-loader": "^16.0.5",
30 | "vue-template-compiler": "^2.7.16"
31 | },
32 | "eslintConfig": {
33 | "root": true,
34 | "env": {
35 | "node": true
36 | },
37 | "extends": [
38 | "plugin:vue/essential",
39 | "eslint:recommended"
40 | ],
41 | "rules": {},
42 | "parserOptions": {
43 | "parser": "babel-eslint"
44 | }
45 | },
46 | "browserslist": [
47 | "> 1%",
48 | "last 2 versions"
49 | ]
50 | }
51 |
--------------------------------------------------------------------------------
/client/src/router/index.js:
--------------------------------------------------------------------------------
1 | // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: MIT-0
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this
5 | // software and associated documentation files (the "Software"), to deal in the Software
6 | // without restriction, including without limitation the rights to use, copy, modify,
7 | // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8 | // permit persons to whom the Software is furnished to do so.
9 | //
10 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
11 | // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
12 | // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
13 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
14 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 |
17 | import Vue from 'vue'
18 | import VueRouter from 'vue-router'
19 | import Dashboard from '../views/Dashboard.vue'
20 |
21 | Vue.use(VueRouter)
22 |
23 | const routes = [
24 | {
25 | path: '/',
26 | name: 'dashboard',
27 | component: Dashboard
28 | }
29 | ]
30 |
31 | const router = new VueRouter({
32 | mode: 'history',
33 | base: process.env.BASE_URL,
34 | routes
35 | })
36 |
37 | export default router
38 |
--------------------------------------------------------------------------------
/client/src/main.js:
--------------------------------------------------------------------------------
1 | // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: MIT-0
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this
5 | // software and associated documentation files (the "Software"), to deal in the Software
6 | // without restriction, including without limitation the rights to use, copy, modify,
7 | // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8 | // permit persons to whom the Software is furnished to do so.
9 | //
10 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
11 | // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
12 | // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
13 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
14 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 |
17 | import Vue from 'vue'
18 | import App from './App.vue'
19 | import router from './router'
20 | import store from './store'
21 | import moment from 'moment'
22 | require('./assets/main.scss')
23 |
24 | Vue.config.productionTip = false
25 |
26 | // filters
27 | Vue.filter('formatDate', function (value) {
28 | return moment(value, 'DD/MMM/YYYY:HH:mm:ss Z').format("YYYY-MM-DD HH:mm:ss A")
29 | })
30 |
31 | new Vue({
32 | router,
33 | store,
34 | render: h => h(App)
35 | }).$mount('#app')
36 |
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Functionless URL Shortner
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/client/src/store/index.js:
--------------------------------------------------------------------------------
1 | // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: MIT-0
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this
5 | // software and associated documentation files (the "Software"), to deal in the Software
6 | // without restriction, including without limitation the rights to use, copy, modify,
7 | // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8 | // permit persons to whom the Software is furnished to do so.
9 | //
10 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
11 | // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
12 | // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
13 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
14 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 |
17 | import Vue from 'vue'
18 | import Vuex from 'vuex'
19 |
20 | Vue.use(Vuex)
21 |
22 | export default new Vuex.Store({
23 | state: {
24 | authorized: false,
25 | links: []
26 | },
27 | mutations: {
28 | authorize(state){
29 | state.authorized = true;
30 | },
31 | deAuthorize(state) {
32 | state.authorized = false;
33 | },
34 | hydrateLinks(state, links) {
35 | state.links = links;
36 | },
37 | drainLinks(state){
38 | state.links.length = 0;
39 | },
40 | addLink(state, link){
41 | state.links.push(link);
42 | },
43 | removeLink(state, ind){
44 | state.links.splice(ind, 1);
45 | },
46 | updateLink(state, link, ind){
47 | state.links[ind] = link;
48 | }
49 | },
50 | getters: {
51 | },
52 | actions: {
53 | },
54 | modules: {
55 | }
56 | })
57 |
--------------------------------------------------------------------------------
/client/README.md:
--------------------------------------------------------------------------------
1 |
16 |
17 | # URL Shortener Client
18 | This application is a simple Vuejs application that interacts with the functionless url shortener.
19 |
20 | 
21 |
22 | ## Requirements
23 | * [Node](https://nodejs.org)
24 | * [Vue CLI](https://cli.vuejs.org/)
25 |
26 | If Node with NPM is already installed simply run.
27 | ```
28 | npm install -g @vue/cli
29 | ```
30 |
31 | ## Setup
32 |
33 | **In order for the local client to work for testing, be sure and set the *UseLocalClient* option when launching the backend stack**
34 |
35 | **The following commands need to be run from within the `client` folder.**
36 |
37 | ### 1. Update the environment variables in the `.env` file.
38 | The client needs some information about the backend. These values were output when you deployed the backend. If you need them again, simply run in your terminal:
39 | ```
40 | aws cloudformation describe-stacks --stack-name URLShortener
41 | ```
42 | Update and save the `.env` file. when you are done it should look "something" like this.
43 |
44 | ```
45 | VUE_APP_NAME=shortener
46 | VUE_APP_API_ROOT=https://fd7c8be3rg.execute-api.us-west-2.amazonaws.com/Prod
47 | VUE_APP_AUTH_DOMAIN=https://shortener.auth.us-west-2.amazoncognito.com
48 | VUE_APP_CLIENT_ID=432p7npp8tf7a8pnb0hg5cbegl
49 | ```
50 |
51 | ### 2. Install NPM dependencies
52 |
53 | ```
54 | npm i
55 | ```
56 |
57 | ### 3. Start the local server
58 | ```
59 | npm run serve
60 | ```
61 |
62 | ### 4. Open the webpage at [http://localhost:8080](http://localhost:8080)
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4 | documentation, we greatly value feedback and contributions from our community.
5 |
6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7 | information to effectively respond to your bug report or contribution.
8 |
9 |
10 | ## Reporting Bugs/Feature Requests
11 |
12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13 |
14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16 |
17 | * A reproducible test case or series of steps
18 | * The version of our code being used
19 | * Any modifications you've made relevant to the bug
20 | * Anything unusual about your environment or deployment
21 |
22 |
23 | ## Contributing via Pull Requests
24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25 |
26 | 1. You are working against the latest source on the *master* branch.
27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29 |
30 | To send us a pull request, please:
31 |
32 | 1. Fork the repository.
33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34 | 3. Ensure local tests pass.
35 | 4. Commit to your fork using clear commit messages.
36 | 5. Send us a pull request, answering any default questions in the pull request interface.
37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38 |
39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41 |
42 |
43 | ## Finding contributions to work on
44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
45 |
46 |
47 | ## Code of Conduct
48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
50 | opensource-codeofconduct@amazon.com with any additional questions or comments.
51 |
52 |
53 | ## Security issue notifications
54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
55 |
56 |
57 | ## Licensing
58 |
59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
60 |
61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
62 |
--------------------------------------------------------------------------------
/client/src/App.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
Welcome to {{ appName }}
78 |
The NEWEST URL shortener on the block.
79 |
80 | We're sorry, that link could not be found.
81 | Sign up or
82 | Log in to register it?
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
194 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
16 |
17 | # Functionless URL Shortener
18 | This app creates a URL shortener without using any compute. All business logic is handled at the Amazon API Gateway level. The basic app will create an API Gateway instance utilizing Cognito for authentication and authorization. It will also create an Amazon DynamoDB table for data storage. It will also create a simple Vuejs application as a demo client.
19 |
20 | Read the blog series about this application:
21 | 1. [Building a serverless URL shortener app without AWS Lambda – part 1](https://aws.amazon.com/blogs/compute/building-a-serverless-url-shortener-app-without-lambda-part-1)
22 | 1. [Building a serverless URL shortener app without AWS Lambda – part 2](https://aws.amazon.com/blogs/compute/building-a-serverless-url-shortener-app-without-lambda-part-2)
23 | 1. [Building a serverless URL shortener app without AWS Lambda – part 3](https://aws.amazon.com/blogs/compute/building-a-serverless-url-shortener-app-without-lambda-part-3)
24 |
25 | ## The Backend
26 |
27 | ### Services Used
28 | * Amazon API Gateway
29 | * Amazon Cognito
30 | * Amazon DynamoDB
31 | * AWS Amplify Console
32 | * Amazon CloudFront *Will cause a lengthy deployment time. See note under **Deploying**
33 | * Amazon S3
34 |
35 |
36 | ### Requirements for deployment
37 | * AWS CLI
38 | * AWS SAM CLI v0.37.0+
39 | * Forked copy of this repository. Instructions for forking a GitHib repository can be found here
40 | * A GitHub personal access token with the *repo* scope as shown below. Instructions for creating a personal access token can be found here
41 |
42 | 
43 |
44 | **Be sure and store you new token in a place that you can find it.**
45 |
46 | ### Deploying
47 |
48 | ***Note: This stack includes an Amazon CloudFront distribution which can take around 30 minutes to create. Don't be alarmed if the deploy seems to hang for a long time.***
49 | In the terminal, use the SAM CLI guided deployment the first time you deploy
50 | ```bash
51 | sam deploy -g
52 | ```
53 |
54 | #### Choose options
55 | You can choose the default for all options except *GithubRepository* and **
56 |
57 | ```bash
58 | ## The name of the CloudFormation stack
59 | Stack Name [URLShortener]:
60 |
61 | ## The region you want to deploy in
62 | AWS Region [us-west-2]:
63 |
64 | ## The name of the application (lowercase no spaces). This must be globally unique
65 | Parameter AppName [shortener]:
66 |
67 | ## Enables public client and local client for testing. (Less secure)
68 | Parameter UseLocalClient [false]:
69 |
70 | ## GitHub forked repository URL
71 | Parameter GithubRepository []:
72 |
73 | ## Github Personal access token
74 | Parameter PersonalAccessToken:
75 |
76 | ## Shows you resources changes to be deployed and requires a 'Y' to initiate deploy
77 | Confirm changes before deploy [y/N]:
78 |
79 | ## SAM needs permission to be able to create roles to connect to the resources in your template
80 | Allow SAM CLI IAM role creation [Y/n]:
81 |
82 | ## Save your choice for later deployments
83 | Save arguments to samconfig.toml [Y/n]:
84 | ```
85 |
86 | SAM will then deploy the AWS CloudFormation stack to your AWS account and provide required outputs for the included client.
87 |
88 | After the first deploy you may re-deploy using `sam deploy` or redeploy with different options using `sam deploy -g`.
89 |
90 | ## The Client
91 |
92 | *The client can also be run locally for debugging. Instructions can be found [here](./client/README.md).*
93 |
94 | The client is a Vue.js application that interfaces with the backend and allows you to authenticate and manage URL links. The client is hosted using Amplify Console. To avoid circular dependencies, we need to provide some information for the client after stack is built. The information needed is provided at the end of the deploy process. If you do not have the information you can run the following:
95 |
96 | ```bash
97 | aws cloudformation describe-stacks --stack-name URLShortener
98 | ```
99 |
100 | We need to add this information to the environment variables for the Amplify Console app. There are two options for adding the variables.
101 |
102 | #### Option 1: using the AWS CLI (Update the *\* to reflect the information returned from the deployment.)
103 |
104 | ```bash
105 | aws amplify update-app --app-id --environment-variables \
106 | VUE_APP_NAME=\
107 | ,VUE_APP_CLIENT_ID=\
108 | ,VUE_APP_API_ROOT=\
109 | ,VUE_APP_AUTH_DOMAIN=
110 | ```
111 |
112 | *Also available in the stack output as **AmplifyEnvironmentUpdateCommand***
113 |
114 | #### Option 2: Amplify Console page
115 | 1. Open the [Amplify Console page](https://us-west-2.console.aws.amazon.com/amplify/home)
116 | 1. On the left side, under **All apps**, choose *Url-Shortner-Client*
117 | 1. Under **App settings** choose *Environment variables*
118 | 1. Choose the *manage variables* button
119 | 1. Choose *add variable*
120 | 1. Fill in the *variable* and it's corresponding *Value*
121 | 1. Leave defaults for *Branches* and *Actions*
122 | 1. Repeat for all four variables
123 | 1. Choose save
124 |
125 | ### Starting the first deployment
126 | After deploying the CloudFormation template, you need to go into the Amplify Console and trigger a build. The CloudFormation template can provision the resources, but can’t trigger a build since it creates resources but cannot trigger actions. This can be done via the AWS CLI.
127 |
128 | #### Option 1: Using the AWS CLI (Update the *\* to reflect the information returned from the deployment.)
129 |
130 | ```bash
131 | aws amplify start-job --app-id --branch-name master --job-type RELEASE
132 | ```
133 | *Also available in the stack output as **AmplifyDeployCommand***
134 |
135 | To check on the status, you can view it on the AWS Amplify Console or run:
136 | ```bash
137 | aws amplify get-job --app-id --branch-name master --job-id
138 | ```
139 |
140 | #### Option 2: Amplify Console page
141 | 1. Open the Amplify Console page
142 | 1. On the left side, under **All apps**, choose *Url-Shortner-Client*
143 | 1. Click *Run build*
144 |
145 | *Note: this is only required for the first build subsequent client builds will be triggered when updates are committed to your forked repository.
146 |
147 | ## Cleanup
148 | 1. Open the CloudFormation console
149 | 1. Locate a stack named *URLShortener*
150 | 1. Select the radio option next to it
151 | 1. Select **Delete**
152 | 1. Select **Delete stack** to confirm
153 |
154 | *Note: If you opted to have access logs (on by default), you may have to delete the S3 bucket manually.
155 |
--------------------------------------------------------------------------------
/client/src/views/Dashboard.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |