diff --git a/package.json b/package.json index ed89617..0b97c21 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@vee-validate/zod": "^4.15.0", + "axios": "^1.7.9", "vee-validate": "^4.15.0", "vue": "3.5.13", "vue-router": "4.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 483947d..f209d8b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@vee-validate/zod': specifier: ^4.15.0 version: 4.15.0(vue@3.5.13(typescript@5.7.3))(zod@3.24.1) + axios: + specifier: ^1.7.9 + version: 1.7.9 vee-validate: specifier: ^4.15.0 version: 4.15.0(vue@3.5.13(typescript@5.7.3)) @@ -483,6 +486,12 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.7.9: + resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -513,6 +522,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -547,6 +560,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -643,6 +660,19 @@ packages: flatted@3.3.2: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -731,6 +761,14 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -803,6 +841,9 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -1324,6 +1365,16 @@ snapshots: argparse@2.0.1: {} + asynckit@0.4.0: {} + + axios@1.7.9: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + balanced-match@1.0.2: {} birpc@0.2.19: {} @@ -1352,6 +1403,10 @@ snapshots: color-name@1.1.4: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + concat-map@0.0.1: {} copy-anything@3.0.5: @@ -1376,6 +1431,8 @@ snapshots: deep-is@0.1.4: {} + delayed-stream@1.0.0: {} + entities@4.5.0: {} esbuild@0.24.2: @@ -1523,6 +1580,14 @@ snapshots: flatted@3.3.2: {} + follow-redirects@1.15.9: {} + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + fsevents@2.3.3: optional: true @@ -1592,6 +1657,12 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -1658,6 +1729,8 @@ snapshots: prelude-ls@1.2.1: {} + proxy-from-env@1.1.0: {} + punycode@2.3.1: {} resolve-from@4.0.0: {} diff --git a/src/api/auth.ts b/src/api/auth.ts new file mode 100644 index 0000000..6016482 --- /dev/null +++ b/src/api/auth.ts @@ -0,0 +1,26 @@ +import axios from 'axios'; + +type LoginBody = { + email: string, + password: string, + returnSecureToken: true +} + +type LoginSuccessResponse = { + idToken: string + email: string + refreshToken: string + expiresIn: string + localId: string + registered: boolean +} + +const login = (values: LoginBody) => { + const url = `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${import.meta.env.VITE_FIREBASE_KEY}`; + return axios.post(url, values); +} + + +export const authApi = { + login +} diff --git a/src/store/modules/auth.module.ts b/src/store/modules/auth.module.ts index 31704a7..c01d0ac 100644 --- a/src/store/modules/auth.module.ts +++ b/src/store/modules/auth.module.ts @@ -1,4 +1,6 @@ import type { Module } from 'vuex'; +import { authApi } from '../../api/auth.ts'; +import { ERROR_MESSAGES } from '../../utils/constants.ts'; const LOCAL_STORAGE_KEY = 'jwt-token'; @@ -20,15 +22,21 @@ const authModule: Module = { }, }, actions: { - async login(context, payload) { + async login(context, payload: {email: string, password: string}) { const { commit } = context; - const token = await new Promise((res) => { - setTimeout(() => { - const token = payload.email + payload.password; - res(token); - }, 1500) - }); - commit('setToken', token); + try { + const { data } = await authApi.login({ + email: payload.email, + password: payload.password, + returnSecureToken: true + }) + + commit('setToken', data.idToken); + } catch (e) { + // @ts-ignore + const message = e.response?.data.error.message as keyof typeof ERROR_MESSAGES; + alert(ERROR_MESSAGES?.[message] || 'Ошибка при попытке авторизации'); + } }, logout(context) { const { commit } = context; diff --git a/src/utils/constants.ts b/src/utils/constants.ts new file mode 100644 index 0000000..6fb88ed --- /dev/null +++ b/src/utils/constants.ts @@ -0,0 +1,3 @@ +export const ERROR_MESSAGES = { + 'INVALID_LOGIN_CREDENTIALS': 'Неправильный логин или пароль', +}