├── .browserslistrc
├── .env.test
├── .eslintrc.js
├── .github
└── workflows
│ └── nodejs.yml
├── .gitignore
├── .nvmrc
├── LICENSE.md
├── Makefile
├── README.md
├── babel.config.js
├── jest.config.js
├── package.json
├── postcss.config.js
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── assets
│ └── logo.png
├── aws-exports.js
├── components
│ ├── Footer.vue
│ ├── Menu.vue
│ └── auth
│ │ └── Alert.vue
├── main.js
├── pages
│ ├── Dashboard.vue
│ ├── Home.vue
│ └── auth
│ │ ├── ChangePassword.vue
│ │ ├── ConfirmPasswordReset.vue
│ │ ├── ConfirmSignUp.vue
│ │ ├── PasswordReset.vue
│ │ ├── SignIn.vue
│ │ ├── SignOut.vue
│ │ └── SignUp.vue
├── router
│ └── index.js
└── store
│ ├── index.js
│ └── modules
│ └── auth.js
├── tests
└── unit
│ └── footer.spec.js
├── vue.config.js
└── yarn.lock
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/.env.test:
--------------------------------------------------------------------------------
1 | IDENTITY_POOL_ID="xx-xxxxxx-x:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
2 | AWS_REGION="xx-xxxxxx-x"
3 | USER_POOL_ID="xx-xxxxxx-x_XXXXXXXXX"
4 | USER_POOL_WEB_CLIENT_ID="XXXXXXXXXXXXXXXXXXXXXXXXXX"
5 | PINPOINT_APP_ID="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: ["plugin:vue/essential", "@vue/prettier"],
7 | rules: {
8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
10 | },
11 | parserOptions: {
12 | parser: "babel-eslint"
13 | },
14 | overrides: [
15 | {
16 | files: [
17 | "**/__tests__/*.{j,t}s?(x)",
18 | "**/tests/unit/**/*.spec.{j,t}s?(x)"
19 | ],
20 | env: {
21 | jest: true
22 | }
23 | }
24 | ]
25 | };
26 |
--------------------------------------------------------------------------------
/.github/workflows/nodejs.yml:
--------------------------------------------------------------------------------
1 | name: Node CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | strategy:
11 | matrix:
12 | node-version: [10.x, 12.x]
13 |
14 | steps:
15 | - uses: actions/checkout@v1
16 | - name: Use Node.js ${{ matrix.node-version }}
17 | uses: actions/setup-node@v1
18 | with:
19 | node-version: ${{ matrix.node-version }}
20 | - name: npm install, build, and test
21 | run: |
22 | yarn
23 | yarn run build --if-present
24 | yarn jest
25 | env:
26 | CI: true
27 |
--------------------------------------------------------------------------------
/.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 |
23 | # Don't commit your aws mobile configuration file
24 | .envrc
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 10
2 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2018 Mark Wolfe
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | ci: clean build deploy
2 |
3 | clean:
4 | rm -rf dist
5 |
6 | build:
7 | yarn build
8 |
9 | deploy:
10 | aws s3 sync dist/ s3://$(S3_HOSTING_BUCKET)/ --delete --acl public-read
11 | aws cloudfront create-invalidation --distribution-id $(DISTRIBUTION_ID) --paths '/*'
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cognito-vue-bootstrap
2 |
3 | This application illustrates how to use the [Amazon Amplify](https://github.com/aws/aws-amplify) with [vue.js](https://vuejs.org/), it includes signup, signin, signout, recover password and account verification using email or sms codes. It uses [bootstrap-vue](https://bootstrap-vue.js.org/) for layout.
4 |
5 | # overview
6 |
7 | This example application currently illustrates the following:
8 |
9 | * Sign Up for an account
10 | * Verify your account by entering verification code which has been sent to you via emailed or SMS
11 | * Dashboard which requires authentication to access
12 | * Change Password
13 | * Recover Password using verification code which has been sent to you via emailed or SMS
14 | * Sign In to the application
15 | * Sign Out of the application
16 |
17 | Demo version is located at https://cognito-vue-bootstrapv2.wolfe.id.au/
18 |
19 | # Build Setup
20 |
21 | Before you start have a read over [What is Amazon Cognito?](http://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html)
22 |
23 | To setup this project you first need to configure an aws mobile project using the following snapshot [CognitoVue](https://console.aws.amazon.com/mobilehub/home#/snapshot/ef9bu3t7nsa8uz).
24 |
25 | For more information on this process see [Exporting and Importing AWS Mobile Hub Projects](https://docs.aws.amazon.com/aws-mobile/latest/developerguide/project-import-export.html)
26 |
27 | Once you have imported the project you will have created:
28 |
29 | * An S3 bucket with Cloudfront for your web application.
30 | * A Cognito pool to store your users
31 | * An analytics project to capture metrics on your users login / failure ect.
32 |
33 | Click on the integrate button in your aws mobile project, the download and extract the cloud config zip file, find `aws-exports.js` inside, and replace this file in `src/` directory.
34 |
35 | I use [yarn](https://yarnpkg.com/) to build and run this project.
36 |
37 | ``` bash
38 | # install dependencies
39 | yarn install
40 |
41 | # serve with hot reload at localhost:8080
42 | yarn serve
43 |
44 | # build for production with minification
45 | yarn build
46 | ```
47 |
48 | Sync all the files from your `dist` directory up to the S3 hosting bucket within your AWS Mobile project using the following command.
49 |
50 | ```
51 | aws --region ap-southeast-2 s3 sync dist/ s3://cognitovuebootstrap-hosting-mobilehub-XXXXXXXXXX/ --delete --acl public-read
52 | ```
53 |
54 | # hosting configuration notes
55 |
56 | To host a website on a custom URL using AWS mobile I have found some changes to the current setup. Navigating to the buckets and CDN configuration is done via the `Hosting And Streaming` panel in the mobile project UI.
57 |
58 | * disable website hosting on the hosting S3 bucket
59 | * add an Error Page which sends any 404 (not found) errors to `/index.html` in cloudfront
60 | * enable redirect http -> https on the origin
61 | * configure a route53 domain for your website
62 | * configure a AWS Certificate Manager (ACM) certificate for your domain
63 | * add an A record in route53 of type `alias` pointing to your Cloudfront distribution, then update the origin domain name to match the FQDN.
64 |
65 | For a more detailed explanation on how things work, checkout:
66 |
67 | * [AWS Amplify Documentation](https://aws.github.io/aws-amplify/)
68 | * [AWS Amplify Modularization](https://github.com/aws-amplify/amplify-js/wiki/Amplify-modularization)
69 | * [docs for vue-cli](https://cli.vuejs.org/)
70 | * [docs for vue-router](http://router.vuejs.org/en/)
71 | * [docs for vuex](https://vuex.vuejs.org/)
72 |
73 | # License
74 |
75 | This project is released under the Apache License, Version 2.0.
76 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["@vue/cli-plugin-babel/preset"]
3 | };
4 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: "@vue/cli-plugin-unit-jest"
3 | };
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cognito-vue-bootstrap",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "test:unit": "vue-cli-service test:unit",
9 | "lint": "vue-cli-service lint"
10 | },
11 | "dependencies": {
12 | "@aws-amplify/auth": "^1.5.0",
13 | "bootstrap-vue": "^2.0.4",
14 | "core-js": "^3.3.2",
15 | "vue": "^2.6.10",
16 | "vue-awesome": "^3.5.4",
17 | "vue-resource": "^1.5.1",
18 | "vue-router": "^3.1.3",
19 | "vuex": "^3.0.1",
20 | "vuex-localstorage": "^1.0.0"
21 | },
22 | "devDependencies": {
23 | "@testing-library/vue": "^4.1.0",
24 | "@vue/cli-plugin-babel": "^4.0.0",
25 | "@vue/cli-plugin-eslint": "^4.0.0",
26 | "@vue/cli-plugin-router": "^4.0.0",
27 | "@vue/cli-plugin-unit-jest": "^4.0.0",
28 | "@vue/cli-plugin-vuex": "^4.0.0",
29 | "@vue/cli-service": "^4.0.0",
30 | "@vue/eslint-config-prettier": "^5.0.0",
31 | "@vue/test-utils": "1.0.0-beta.29",
32 | "babel-eslint": "^10.0.3",
33 | "eslint": "^5.16.0",
34 | "eslint-plugin-prettier": "^3.1.1",
35 | "eslint-plugin-vue": "^5.0.0",
36 | "prettier": "^1.18.2",
37 | "vue-template-compiler": "^2.6.10"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | autoprefixer: {}
4 | }
5 | };
6 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wolfeidau/cognito-vue-bootstrap/84801f7fa56327c92fc500c2622e7b818b2ce9c1/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | cognito-vue-bootstrapv3
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
25 |
26 |
58 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wolfeidau/cognito-vue-bootstrap/84801f7fa56327c92fc500c2622e7b818b2ce9c1/src/assets/logo.png
--------------------------------------------------------------------------------
/src/aws-exports.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | // To get the AWS Credentials, you need to configure
3 | // the Auth module with your Cognito Federated Identity Pool
4 | Auth: {
5 | identityPoolId: process.env.IDENTITY_POOL_ID,
6 | region: process.env.AWS_REGION,
7 | userPoolId: process.env.USER_POOL_ID,
8 | userPoolWebClientId: process.env.USER_POOL_WEB_CLIENT_ID,
9 | mandatorySignIn: false,
10 | clientMetadata: { app: "cognito-vue-bootstrap" }
11 | },
12 | Analytics: {
13 | disabled: false,
14 | autoSessionRecord: true,
15 | AWSPinpoint: {
16 | appId: process.env.PINPOINT_APP_ID,
17 | region: process.env.AWS_REGION
18 | }
19 | }
20 | };
21 |
22 | export default config;
23 |
--------------------------------------------------------------------------------
/src/components/Footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
14 |
15 |
26 |
--------------------------------------------------------------------------------
/src/components/Menu.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Cognito Bootstrap
5 |
6 | Dashboard
7 |
8 |
9 | Sign In
12 |
13 |
14 | {{
15 | user.username
16 | }}
17 |
18 |
19 | Change Password
22 | Sign Out
27 |
28 |
29 |
32 |
37 |
38 |
39 |
40 |
41 |
64 |
65 |
77 |
--------------------------------------------------------------------------------
/src/components/auth/Alert.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ authenticationStatus.message }}.
7 |
8 |
9 |
22 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import BootstrapVue from "bootstrap-vue";
3 | import App from "@/App.vue";
4 | import router from "@/router";
5 | import store from "@/store";
6 | import Auth from "@aws-amplify/auth";
7 | import AuthConfig from "@/aws-exports";
8 |
9 | Auth.configure(AuthConfig);
10 |
11 | Vue.use(BootstrapVue);
12 |
13 | Vue.config.productionTip = false;
14 |
15 | new Vue({
16 | router,
17 | store,
18 | el: "#app",
19 | render: h => h(App)
20 | });
21 |
--------------------------------------------------------------------------------
/src/pages/Dashboard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Cognito Bootstrap Vue
5 |
You are logged in as {{ user.username }}.
6 |
7 |
8 |
9 |
10 |
21 |
--------------------------------------------------------------------------------
/src/pages/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Cognito Bootstrap Vue
5 |
6 | This site provides an example of how to use
7 | Amazon Cognito
8 | with Vue.js
9 |
10 |
To give it a try:
11 |
12 | -
13 | Sign up using your email address, this will send through an activation
14 | code.
15 |
16 | -
17 | Once you get the activation code enter it with your email address.
18 |
19 | - Sign in with your credentials.
20 | - Request a password reset to recover an account.
21 | - Change your password.
22 |
23 |
24 | Sign Up
25 |
26 |
27 | The full source code for this example application is available here:
28 |
29 |
30 | -
31 | https://github.com/wolfeidau/cognito-vue-bootstrap
34 |
35 |
36 |
37 |
38 |
39 |
40 |
43 |
--------------------------------------------------------------------------------
/src/pages/auth/ChangePassword.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
77 |
--------------------------------------------------------------------------------
/src/pages/auth/ConfirmPasswordReset.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
99 |
--------------------------------------------------------------------------------
/src/pages/auth/ConfirmSignUp.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Confirm Sign Up
7 |
8 |
16 |
17 |
18 |
25 |
26 | Submit
29 | Resend Code
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
82 |
--------------------------------------------------------------------------------
/src/pages/auth/PasswordReset.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
64 |
--------------------------------------------------------------------------------
/src/pages/auth/SignIn.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
30 |
31 |
32 |
33 |
34 |
35 | Create an account or
36 | reset password
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/src/pages/auth/SignOut.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Sign Out...
5 |
6 |
7 |
8 |
9 |
19 |
--------------------------------------------------------------------------------
/src/pages/auth/SignUp.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
106 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Router from "vue-router";
3 | import Home from "@/pages/Home.vue";
4 | import Dashboard from "@/pages/Dashboard.vue";
5 | import SignIn from "@/pages/auth/SignIn.vue";
6 | import SignUp from "@/pages/auth/SignUp.vue";
7 | import SignOut from "@/pages/auth/SignOut.vue";
8 | import ConfirmSignUp from "@/pages/auth/ConfirmSignUp.vue";
9 | import PasswordReset from "@/pages/auth/PasswordReset.vue";
10 | import ChangePassword from "@/pages/auth/ChangePassword.vue";
11 | import ConfirmPasswordReset from "@/pages/auth/ConfirmPasswordReset.vue";
12 |
13 | import store from "@/store";
14 |
15 | Vue.use(Router);
16 |
17 | const routes = [
18 | {
19 | path: "/",
20 | name: "home",
21 | component: Home,
22 | meta: { title: "Home", auth: false }
23 | },
24 | {
25 | path: "/dashboard",
26 | name: "dashboard",
27 | component: Dashboard,
28 | meta: { title: "Dashboard", auth: true }
29 | },
30 | {
31 | path: "/signIn",
32 | name: "signIn",
33 | component: SignIn,
34 | meta: { title: "Sign In", auth: false }
35 | },
36 | {
37 | path: "/signOut",
38 | name: "signOut",
39 | component: SignOut,
40 | meta: { title: "Sign Out", auth: true }
41 | },
42 | {
43 | path: "/signUp",
44 | name: "signUp",
45 | component: SignUp,
46 | meta: { title: "Sign Up", auth: false }
47 | },
48 | {
49 | path: "/confirmSignUp",
50 | name: "confirmSignUp",
51 | component: ConfirmSignUp,
52 | meta: { title: "Confirm SignUp", auth: false }
53 | },
54 | {
55 | path: "/changePassword",
56 | name: "changePassword",
57 | component: ChangePassword,
58 | meta: { title: "Change Password", auth: true }
59 | },
60 | {
61 | path: "/passwordReset",
62 | name: "passwordReset",
63 | component: PasswordReset,
64 | meta: { title: "Password Reset", auth: false }
65 | },
66 | {
67 | path: "/confirmPasswordReset",
68 | name: "confirmPasswordReset",
69 | component: ConfirmPasswordReset,
70 | meta: { title: "Confirm Password Reset", auth: false }
71 | }
72 | ];
73 |
74 | const router = new Router({ mode: "history", routes });
75 |
76 | // this routine will ensure that any pages marked as `auth` in the `meta` section are
77 | // protected from access by unauthenticated users.
78 | router.beforeEach((to, from, next) => {
79 | // Use the page's router title to name the page
80 | if (to.meta && to.meta.title) {
81 | document.title = to.meta.title;
82 | }
83 |
84 | // is there a meta and auth attribute?
85 | if (to.meta && to.meta.auth !== undefined) {
86 | // if the page requires auth
87 | if (to.meta.auth) {
88 | // and we are authenticated?
89 | if (store.getters["auth/isAuthenticated"]) {
90 | next(); // route normally
91 | return;
92 | }
93 | // otherwise off to the sign in page
94 | router.push({ name: "signIn" });
95 | return;
96 | }
97 | // otherwise are we already authenticated?
98 | if (store.getters["auth/isAuthenticated"]) {
99 | // yes we are, so off to dashboard
100 | router.push({ name: "dashboard" });
101 | return;
102 | }
103 | next(); // route normally
104 | return;
105 | }
106 | next(); // route normally
107 | return;
108 | });
109 |
110 | export default router;
111 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Vuex from "vuex";
3 | import createPersist from "vuex-localstorage";
4 |
5 | Vue.use(Vuex);
6 |
7 | // Modules
8 | import auth from "./modules/auth";
9 |
10 | const debug = process.env.NODE_ENV !== "production";
11 |
12 | const store = new Vuex.Store({
13 | modules: {
14 | auth
15 | },
16 | strict: debug,
17 | plugins: [
18 | createPersist({
19 | namespace: "cognito-vue-bootstrap",
20 | initialState: {},
21 | // ONE_WEEK
22 | expires: 7 * 24 * 60 * 60 * 1e3
23 | })
24 | ]
25 | });
26 |
27 | export default store;
28 |
--------------------------------------------------------------------------------
/src/store/modules/auth.js:
--------------------------------------------------------------------------------
1 | import Auth from "@aws-amplify/auth";
2 | import Amplify from "@aws-amplify/core";
3 |
4 | const Logger = Amplify.Logger;
5 | Logger.LOG_LEVEL = "DEBUG"; // to show detailed logs from Amplify library
6 | const logger = new Logger("store:auth");
7 |
8 | // initial state
9 | const state = {
10 | user: null,
11 | isAuthenticated: false,
12 | authenticationStatus: null
13 | };
14 |
15 | const getters = {
16 | authenticatedUser: state => state.user,
17 | isAuthenticated: state => state.isAuthenticated,
18 | authenticationStatus: state => {
19 | return state.authenticationStatus
20 | ? state.authenticationStatus
21 | : { variant: "secondary" };
22 | },
23 | hasAuthenticationStatus: state => {
24 | return !!state.authenticationStatus;
25 | }
26 | };
27 |
28 | const mutations = {
29 | setAuthenticationError(state, err) {
30 | logger.debug("auth error: {}", err);
31 | state.authenticationStatus = {
32 | state: "failed",
33 | message: err.message,
34 | variant: "danger"
35 | };
36 | },
37 | clearAuthenticationStatus: state => {
38 | state.authenticationStatus = null;
39 | },
40 | setUserAuthenticated(state, user) {
41 | state.user = user;
42 | state.isAuthenticated = true;
43 | },
44 | clearAuthentication(state) {
45 | state.user = null;
46 | state.userId = null;
47 | state.isAuthenticated = false;
48 | }
49 | };
50 |
51 | const actions = {
52 | clearAuthenticationStatus: context => {
53 | context.commit("clearAuthenticationStatus", null);
54 | },
55 | signIn: async (context, params) => {
56 | logger.debug("signIn for {}", params.username);
57 | context.commit("auth/clearAuthenticationStatus", null, { root: true });
58 | try {
59 | const user = await Auth.signIn(params.username, params.password);
60 | context.commit("setUserAuthenticated", user);
61 | } catch (err) {
62 | context.commit("auth/setAuthenticationError", err, { root: true });
63 | }
64 | },
65 | signOut: async context => {
66 | try {
67 | await Auth.signOut();
68 | } catch (err) {
69 | logger.error("error during sign out: {}", err);
70 | }
71 | context.commit("auth/clearAuthentication", null, { root: true });
72 | },
73 | signUp: async (context, params) => {
74 | context.commit("auth/clearAuthenticationStatus", null, { root: true });
75 | try {
76 | await Auth.signUp(params);
77 | context.commit("auth/clearAuthentication", null, { root: true });
78 | } catch (err) {
79 | context.commit("auth/setAuthenticationError", err, { root: true });
80 | }
81 | },
82 | confirmSignUp: async (context, params) => {
83 | logger.debug("confirm signup for {}", params.username);
84 | context.commit("auth/clearAuthenticationStatus", null, { root: true });
85 | try {
86 | await Auth.confirmSignUp(params.username, params.code);
87 | } catch (err) {
88 | context.commit("auth/setAuthenticationError", err, { root: true });
89 | }
90 | },
91 | confirmResend: async (context, params) => {
92 | context.commit("auth/clearAuthenticationStatus", null, { root: true });
93 | try {
94 | await Auth.resendSignUp(params.username);
95 | } catch (err) {
96 | context.commit("auth/setAuthenticationError", err, { root: true });
97 | }
98 | },
99 | passwordReset: async (context, params) => {
100 | context.commit("auth/clearAuthenticationStatus", null, { root: true });
101 | try {
102 | await Auth.forgotPassword(params.username);
103 | } catch (err) {
104 | context.commit("auth/setAuthenticationError", err, { root: true });
105 | }
106 | },
107 | confirmPasswordReset: async (context, params) => {
108 | context.commit("auth/clearAuthenticationStatus", null, { root: true });
109 | try {
110 | await Auth.forgotPasswordSubmit(
111 | params.username,
112 | params.code,
113 | params.password
114 | );
115 | } catch (err) {
116 | context.commit("auth/setAuthenticationError", err, { root: true });
117 | }
118 | },
119 | passwordResetResend: async (context, params) => {
120 | context.commit("auth/clearAuthenticationStatus", null, { root: true });
121 | try {
122 | await Auth.passwordResetResend(params.username);
123 | } catch (err) {
124 | context.commit("auth/setAuthenticationError", err, { root: true });
125 | }
126 | },
127 | passwordChange: async (context, params) => {
128 | logger.debug("password change for {}", context.state.user.username);
129 | context.commit("auth/clearAuthenticationStatus", null, { root: true });
130 | try {
131 | const user = await Auth.currentAuthenticatedUser();
132 | await Auth.changePassword(
133 | user,
134 | params.currentPassword,
135 | params.newPassword
136 | );
137 | } catch (err) {
138 | context.commit("auth/setAuthenticationError", err, { root: true });
139 | }
140 | }
141 | };
142 |
143 | export default {
144 | namespaced: true,
145 | state,
146 | getters,
147 | actions,
148 | mutations
149 | };
150 |
--------------------------------------------------------------------------------
/tests/unit/footer.spec.js:
--------------------------------------------------------------------------------
1 | import { render } from '@testing-library/vue'
2 | import Footer from "@/components/Footer.vue";
3 |
4 | describe("Footer.vue", () => {
5 | it("renders props.msg when passed", () => {
6 | const { getByText } = render(Footer)
7 | getByText('© 2018 Company, Inc.')
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | // vue.config.js
2 | module.exports = {
3 | transpileDependencies: [/\bvue-awesome\b/]
4 | };
5 |
--------------------------------------------------------------------------------