diff --git a/.env b/.env index a8d4e90..701faa6 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ VUE_APP_ROOT_URL=http://localhost:8080 VUE_APP_ROOT_API=http://localhost:9090/api -VUE_APP_PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3MRA7zxvaWKrtmPl2hRJLFiyryvj0ZUlmWw9OZIgqwJUDBTsg5yFX4hCQrANV1yy5ibTqAn2APdNCdhGgp8R2YLWrUR2vVGbmnKXXzEDsFpT6cgo \ No newline at end of file +VUE_APP_PUBLIC_KEY="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkclHj0FpIPiB+XQL0P/mJVUdYbRXYS9vjSbVllzVteZgVDhK/srybDmAM2PSn8ZlakUa9bkBAGmiozaccDRJx5DJ/C80hIUcQneDKqWuY6rgnT3zKhjt3MHZK0I2VX5t7QgWHdh5Dni/D08JWwTkbnH+qhz8Wb4xlV0HokQB05YB00deuO09fr5Qw3GjgSSK8HA+euoajgijMbRPuReA4nkmBLhyTMryX/1h9vi8Wz9reGeiFdLZLECrcMmbLRF3d8iC/HISqBYdqdyjvGhXzGu19Gog1Qt8/qNh4fPmB0Le3EpfjRkcWrLqi22N7cGRAvagCJJAzqQVKe5S2fTVRwIDAQAB" diff --git a/package-lock.json b/package-lock.json index 12da592..fe8f13f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "hasInstallScript": true, "dependencies": { + "axios": "^1.4.0", "core-js": "^3.8.3", "devextreme": "^22.2.4", "devextreme-vue": "^22.2.4", @@ -3763,9 +3764,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "optional": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/at-least-node": { "version": "1.0.0", @@ -3837,6 +3836,29 @@ "dev": true, "optional": true }, + "node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/babel-loader": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", @@ -4768,8 +4790,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "optional": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -5609,8 +5629,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "optional": true, "engines": { "node": ">=0.4.0" } @@ -7285,7 +7303,6 @@ "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true, "funding": [ { "type": "individual", @@ -9358,7 +9375,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -9367,7 +9383,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -11068,6 +11083,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", diff --git a/package.json b/package.json index e57425e..9de1833 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "postinstall": "npm run build-themes" }, "dependencies": { + "axios": "^1.4.0", "core-js": "^3.8.3", "devextreme": "^22.2.4", "devextreme-vue": "^22.2.4", diff --git a/src/auth.js b/src/auth.js index a4c45ed..4da7601 100644 --- a/src/auth.js +++ b/src/auth.js @@ -1,58 +1,54 @@ -const defaultUser = { - email: 'titan@hadiyan.net', - avatarUrl: 'https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/06.png' -}; +import * as Forge from 'node-forge' +import axios from 'axios' +import { useRouter } from 'vue-router' + +const router = useRouter() export default { - _user: defaultUser, + _user: null, + loggedIn() { - return !!this._user; + let user = JSON.parse(window.localStorage.getItem('user')); + let access_token = window.localStorage.getItem('access_token'); + + if (user && access_token) { + axios.defaults.headers['authorization'] = `Bearer ${access_token}`; + return !!user; + } + + return false; }, async logIn(email, password) { try { - // Send request - console.log(email, password); - // this._user = { ...defaultUser, email }; - // return { - // isOk: true, - // data: this._user - // }; + const response = await axios.post('authentication/login', { + email, + password: this.encrypt(password), + }); - const requestOptions = { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ email: email, password: password }), + const data = response.data; + + this._user = { + username: data.data.username, + email: data.data.email, + role: data.data.role, + avatarUrl: 'https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/06.png', }; - const response = await fetch('http://localhost:9090/api/authentication/login', requestOptions); - const data = await response.json(); + window.localStorage.setItem('user', JSON.stringify(this._user)) + window.localStorage.setItem('access_token', response.data.data.accessToken) + window.localStorage.setItem('refresh_token', response.data.data.refreshToken) - console.log(data); - //console.log(data.data.length); - - // this._user = { - // id: response.data.id, - // email: response.data.role, - // name: response.data.keterangan, - // role_id: response.data.id, - // }; - - if(data.status == 'sukses') { - const defaultUser = { - email: data.data.email, - avatarUrl: 'https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/06.png', - name: data.data.name, - }; - this._user = { ...defaultUser }; + axios.defaults.headers['authorization'] = `Bearer ${response.data.data.accessToken}`; + if (response.status === 200) { return { isOk: true, data: this._user }; } else { - //--- jika gagal munculkan pesan gagal + return { isOk: false, message: "Authentication failed" @@ -70,16 +66,27 @@ export default { async logOut() { this._user = null; + window.localStorage.removeItem('user'); + window.localStorage.removeItem('access_token'); + window.localStorage.removeItem('refresh_token'); + await axios.post('authentication/logout') + axios.defaults.headers['authorization'] = null; + router.push({ name: 'login-form' }) }, async getUser() { try { - // Send request + const user = JSON.parse(window.localStorage.getItem('user')); + + if (user) { + return { + isOk: true, + data: user, + }; + } + + throw new Error(`Could not find current logged in user.`); - return { - isOk: true, - data: this._user - }; } catch { return { @@ -137,5 +144,23 @@ export default { message: "Failed to create account" }; } - } + }, + + encrypt(param) { + + const publicKey = `-----BEGIN PUBLIC KEY----- +${process.env.VUE_APP_PUBLIC_KEY} +-----END PUBLIC KEY-----` + + const rsa = Forge.pki.publicKeyFromPem(publicKey) + + const encrypted = rsa.encrypt(param, 'RSA-OAEP', { + md: Forge.md.sha256.create(), + mgf1: { + md: Forge.md.sha1.create(), + }, + }); + + return btoa(encrypted) + }, }; diff --git a/src/main.js b/src/main.js index c812b8b..772f1af 100644 --- a/src/main.js +++ b/src/main.js @@ -4,10 +4,13 @@ import './themes/generated/theme.additional.css'; import { createApp } from "vue"; import router from "./router"; import themes from "devextreme/ui/themes"; +import axios from 'axios' import App from "./App"; import appInfo from "./app-info"; +axios.defaults.baseURL = `${process.env.VUE_APP_ROOT_API}`; + themes.initialized(() => { const app = createApp(App); app.use(router); diff --git a/src/router.js b/src/router.js index 817865e..0391e32 100644 --- a/src/router.js +++ b/src/router.js @@ -121,7 +121,7 @@ const router = new createRouter({ { path: "/:pathMatch(.*)*", redirect: "/home" - }, + }, { path: "/user-page", name: "user-page", @@ -130,7 +130,7 @@ const router = new createRouter({ layout: defaultLayout }, component: User - }, + }, { path: "/master-data/jenis-pengadaan", name: "jenis-pengadaan", @@ -139,7 +139,7 @@ const router = new createRouter({ layout: defaultLayout }, component: JenisPengadaan - }, + }, { path: "/master-data/unit-inisiator", name: "unit-inisiator", @@ -148,7 +148,7 @@ const router = new createRouter({ layout: defaultLayout }, component: UnitInisiator - }, + }, { path: "/master-data/metode-pengadaan", name: "metode-pengadaan", @@ -157,7 +157,7 @@ const router = new createRouter({ layout: defaultLayout }, component: MetodePengadaan - }, + }, { path: "/master-data/metode-penyampaian", name: "metode-penyampaian", @@ -175,7 +175,7 @@ const router = new createRouter({ layout: defaultLayout }, component: JenisKontrak - }, + }, { path: "/master-data/sumber-dana", name: "sumber-dana", @@ -184,7 +184,7 @@ const router = new createRouter({ layout: defaultLayout }, component: SumberDana - }, + }, { path: "/master-data/strategi-pengadaan", name: "strategi-pengadaan", @@ -193,7 +193,7 @@ const router = new createRouter({ layout: defaultLayout }, component: StrategiPengadaan - }, + }, { path: "/master-data/lokasi-pengadaan", name: "lokasi-pengadaan", @@ -202,7 +202,7 @@ const router = new createRouter({ layout: defaultLayout }, component: LokasiPengadaan - }, + }, { path: "/master-data/supply-positioning-matrix", name: "supply-positioning-matrix", @@ -211,7 +211,7 @@ const router = new createRouter({ layout: defaultLayout }, component: SupplyPositioningMatrix - }, + }, { path: "/master-data/jenis-anggaran", name: "jenis-anggaran", @@ -229,7 +229,7 @@ const router = new createRouter({ layout: defaultLayout }, component: InstansiPage - }, + }, { path: "/master-data/bidang-page", name: "bidang-page", @@ -238,7 +238,7 @@ const router = new createRouter({ layout: defaultLayout }, component: BidangPage - }, + }, { path: "/master-data/jabatan-page", name: "jabatan-page", @@ -256,7 +256,7 @@ const router = new createRouter({ layout: defaultLayout }, component: RolesConfig - }, + }, { path: "/master-config/users-config", name: "users-config", @@ -265,7 +265,7 @@ const router = new createRouter({ layout: defaultLayout }, component: UsersConfig - }, + }, { path: "/master-config/permissions-config", name: "permissions-config", @@ -274,7 +274,7 @@ const router = new createRouter({ layout: defaultLayout }, component: PermissionsConfig - }, + }, { path: "/rks-daftar", name: "rks-daftar", @@ -294,7 +294,7 @@ const router = new createRouter({ component: DrpPenyusunan }, - + ], history: createWebHashHistory() }); diff --git a/src/views/login-form.vue b/src/views/login-form.vue index ba87bcb..8c8842c 100644 --- a/src/views/login-form.vue +++ b/src/views/login-form.vue @@ -2,56 +2,42 @@