diff --git a/fda-ui/api/api.js b/fda-ui/api/api.js new file mode 100644 index 0000000000000000000000000000000000000000..8c08db991372adb36630bbbde5e12148ca00209b --- /dev/null +++ b/fda-ui/api/api.js @@ -0,0 +1,14 @@ +import https from 'https' +import axios from 'axios' +import api from '@/config' + +const httpsAgent = new https.Agent({ rejectUnauthorized: false }) + +const instance = axios.create({ + baseURL: api, + timeout: 10000, + params: {}, + httpsAgent +}) + +export default instance diff --git a/fda-ui/api/authentication.service.js b/fda-ui/api/authentication.service.js new file mode 100644 index 0000000000000000000000000000000000000000..78bacea4b2d6232f9aebd92101374dc56bcc2b56 --- /dev/null +++ b/fda-ui/api/authentication.service.js @@ -0,0 +1,28 @@ +import Vue from 'vue' +import qs from 'qs' +import api from '@/api/api' +import { api as endpoint, clientSecret } from '@/config' + +class AuthenticationService { + authenticate (username, password) { + const payload = { + client_id: 'dbrepo-client', + username, + password, + grant_type: 'password', + client_secret: clientSecret, + scope: 'openid profile roles' + } + api.post(`${endpoint.replace('http:', 'https:')}/api/auth/realms/dbrepo/protocol/openid-connect/token`, qs.stringify(payload), { + headers: { ContentType: 'application/form-data' } + }).then((response) => { + console.info('====>', response) + }).catch((error) => { + console.error('Failed to authenticate', error) + const { code, message } = error + Vue.$toast.error(`[${code}] Failed to authenticate: ${message}`) + }) + } +} + +export default new AuthenticationService() diff --git a/fda-ui/api/user/index.js b/fda-ui/api/user/index.js index 3d8cc4f73825ce4e6c126c7cc4db1244644bb479..dd32580f3386a0d1c50fc3cd9d42b414fa9cc8a8 100644 --- a/fda-ui/api/user/index.js +++ b/fda-ui/api/user/index.js @@ -1,24 +1,10 @@ // eslint-disable-next-line camelcase import jwt_decode from 'jwt-decode' -const axios = require('axios/dist/browser/axios.cjs') +import api from '../api' const qs = require('qs') -export function authenticate (clientSecret, username, password) { - const payload = { - client_id: 'dbrepo-client', - username, - password, - grant_type: 'password', - client_secret: clientSecret, - scope: 'openid profile roles' - } - return axios.post('/api/auth/realms/dbrepo/protocol/openid-connect/token', qs.stringify(payload), { - headers: { ContentType: 'application/form-data' } - }) -} - export function updateUser (token, userId, data) { - return axios.put(`/api/user/${userId}`, data, { + return api.put(`/api/user/${userId}`, data, { headers: { Authorization: `Bearer ${token}` } @@ -29,7 +15,7 @@ export function updateUserPassword (token, userId, password) { const payload = { password } - return axios.put(`/api/user/${userId}/password`, payload, { + return api.put(`/api/user/${userId}/password`, payload, { headers: { Authorization: `Bearer ${token}` } @@ -40,7 +26,7 @@ export function toggleUserTheme (token, userId, themeDark) { const payload = { theme_dark: themeDark } - return axios.put(`/api/user/${userId}/theme`, payload, { + return api.put(`/api/user/${userId}/theme`, payload, { headers: { Authorization: `Bearer ${token}` } @@ -49,7 +35,7 @@ export function toggleUserTheme (token, userId, themeDark) { export function findUser (token) { const user = tokenToUser(token) - return axios.get(`/api/user/${user.id}`, { + return api.get(`/api/user/${user.id}`, { headers: { Authorization: `Bearer ${token}` } @@ -63,7 +49,7 @@ export function refresh (clientSecret, token) { client_secret: clientSecret, refresh_token: token } - return axios.post('/api/auth/realms/dbrepo/protocol/openid-connect/token', qs.stringify(payload), { + return api.post('/api/auth/realms/dbrepo/protocol/openid-connect/token', qs.stringify(payload), { headers: { ContentType: 'application/form-data' } }) } diff --git a/fda-ui/config.js b/fda-ui/config.js index 9cce6f7341a6fd088bec683edfa7053fe92e4507..b2ea4ef41e7c38bb63c62df110c71fbfd78cb82d 100644 --- a/fda-ui/config.js +++ b/fda-ui/config.js @@ -1,6 +1,6 @@ const config = {} -config.api = process.env.API || 'http://gateway-service:9095' +config.api = process.env.API || 'http://localhost:9095' config.search = process.env.SEARCH || 'http://localhost:9200' config.sandbox = process.env.SANDBOX || false config.title = process.env.TITLE || 'Database Repository' diff --git a/fda-ui/nuxt.config.js b/fda-ui/nuxt.config.js index 82cc9deecfc8c54bed971a267985eb974077b6a0..0f3697cc50e764aca13fbe3375fd23f69ea80767 100644 --- a/fda-ui/nuxt.config.js +++ b/fda-ui/nuxt.config.js @@ -2,10 +2,6 @@ import path from 'path' import colors from 'vuetify/es5/util/colors' import { sandbox, title, icon, brokerUsername, brokerPassword, sharedFilesystem, version, logo, mailVerify, tokenMax, elasticPassword, clientSecret, api, search, defaultPublisher } from './config' -if (sandbox) { - console.info('[FDA] Running in sandbox environment') -} - export default { target: 'server', ssr: false, diff --git a/fda-ui/pages/login.vue b/fda-ui/pages/login.vue index 3cd0247d196ca6d0f35227ce8c41d9ae697c2899..a1c04ad0c3c809f4e9a806bb78eb1fba202f850c 100644 --- a/fda-ui/pages/login.vue +++ b/fda-ui/pages/login.vue @@ -58,7 +58,8 @@ </template> <script> -import { authenticate, getThemeDark, findUser, tokenToRoles } from '@/api/user' +import { getThemeDark, findUser } from '@/api/user' +import authenticationService from '@/api/authentication.service' export default { data () { return { @@ -107,23 +108,21 @@ export default { submit () { this.$refs.form.validate() }, - async login () { - try { - this.loading = true - const res = await authenticate(this.clientSecret, this.username, this.password) - // eslint-disable-next-line camelcase - const { access_token } = res.data - this.$store.commit('SET_TOKEN', access_token) - const roles = tokenToRoles(access_token) - this.$store.commit('SET_ROLES', roles) - await this.setTheme() - await this.$router.push({ path: this.$route.query.redirect ? this.$route.query.redirect : '/container' }) - } catch (error) { - console.error('Failed to login', error) - const { statusText } = error.response - this.$toast.error(`Failed to login: ${statusText}`) - this.loading = false - } + login () { + this.loading = true + authenticationService.authenticate(this.username, this.password) + // // eslint-disable-next-line camelcase + // const { access_token } = res.data + // this.$store.commit('SET_TOKEN', access_token) + // const roles = tokenToRoles(access_token) + // this.$store.commit('SET_ROLES', roles) + // await this.setTheme() + // await this.$router.push({ path: this.$route.query.redirect ? this.$route.query.redirect : '/container' }) + // } catch (error) { + // console.error('Failed to login', error) + // const { statusText } = error.response + // this.$toast.error(`Failed to login: ${statusText}`) + // this.loading = false }, async setTheme () { try { diff --git a/fda-ui/plugins/axios.js b/fda-ui/plugins/axios.js index 7d7226e720072556415b1583a018b30718462420..384459494898185ed76aaea5bc58b5d4e042236b 100644 --- a/fda-ui/plugins/axios.js +++ b/fda-ui/plugins/axios.js @@ -1,21 +1,20 @@ import Vue from 'vue' -import axios from 'axios' -import api from '../config' -import updateToken from '../server-middleware/update-token' +import api from '@/api/api' -const instance = axios.create({ - baseURL: api, - timeout: 10000, - params: {} -}) - -instance.interceptors.request.use(async (config) => { - const token = await updateToken() - config.headers.common.Authorization = `Bearer ${token}` - return config +api.interceptors.request.use((config) => { + console.debug('loading token', Vue.$keycloak.token, Vue.$keycloak.refreshToken) + Vue.$keycloak.updateToken(70) + .then(() => { + const token = String(Vue.$keycloak.token) + config.headers.common.Authorization = `Bearer ${token}` + return config + }) + .catch((error) => { + console.error('Failed to update token', error) + }) }, function (error) { // Do something with request error return Promise.reject(error) }) -Vue.use(instance) +Vue.use(api) diff --git a/fda-ui/root.crt b/fda-ui/root.crt new file mode 100644 index 0000000000000000000000000000000000000000..798a1f673479c075782eeed6458beb2d7d693e07 --- /dev/null +++ b/fda-ui/root.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPzCCAiegAwIBAgIEHaMDRDANBgkqhkiG9w0BAQsFADBBMQswCQYDVQQGEwJB +VDEQMA4GA1UEChMHVFUgV2llbjEPMA0GA1UECxMGRFMtSUZTMQ8wDQYDVQQDEwZS +b290Q0EwHhcNMjMwNDAzMTczOTU5WhcNMzMwMjA5MTczOTU5WjBBMQswCQYDVQQG +EwJBVDEQMA4GA1UEChMHVFUgV2llbjEPMA0GA1UECxMGRFMtSUZTMQ8wDQYDVQQD +EwZSb290Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCK8FuP0bGt +QAvhZEjRWTQuCdE6vXpDWjvSoevZaSclgJ9SncDHtRzkH0x0ArVfIRZFtjSUEcHb +2r8mnOvqQ+9vs2azjTlacdPvezbhfgFFGIdrnHSm3RTB7smeOFceFkIvwiXT49+y +ZGkB/p0QCDoVYhgRxFNtZKBTYa0uJLQ7cM8LK2g66/yugJsB4zOlre1zPiWGY/5k +sWu780XVKpl9j6CR/xp3012bKlT/t7j7fKRamJYVYtW2guRQnl5J5AKRzlRGh84G +onNI5qiwS0gAZUajpL00lb2XxSkv11DY0743EOSsqOvUDr+5h4v7pXEt+O5aFvFN +ewRTHON1624fAgMBAAGjPzA9MB0GA1UdDgQWBBSdLp+I30uB4jAMP1PnZLolxbF/ +AzALBgNVHQ8EBAMCAgQwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AQEAIqrbs8mXC07a8VURnu3EFxO3dliDgxY1yQfB0VqMFL1yxGKXrVAJFLP/1MVr +HVx53vZd/KBNGUjhLfnj3vF+TpqnOoJ/QEDSJPuEnpfFPtx0tE3e3lQQlebIA8aM +m1iP2SJuKAYQUYOg1N9XXa+UPs9tWWrllY5dcYdHOK168eUwo1h6v0OOnaP7RvSn +457jewK6fJ3tUhox2Hu1JEowupYE5QhMiLwG30MGkf2pWkTNfz005LTzmgvfMSz7 +k1rfO9oKdVbxNYxZPdzKZRsnCfOka/MmYcXstjp5KKXLo4Z3LLs8N0GDWlKRvX9p +z2CJQ6CG+Aws4+J3mFOm2G9rIw== +-----END CERTIFICATE----- diff --git a/fda-ui/server-middleware/update-token.js b/fda-ui/server-middleware/update-token.js deleted file mode 100644 index 0e28d3473bfd37db4786e289385d255c4849bf0c..0000000000000000000000000000000000000000 --- a/fda-ui/server-middleware/update-token.js +++ /dev/null @@ -1,11 +0,0 @@ -import Vue from 'vue' - -export default async function () { - console.debug('loading token') - try { - await Vue.$keycloak.updateToken(70) - return String(Vue.$keycloak.token) - } catch (error) { - console.error('Failed to update token', error) - } -} diff --git a/fda-ui/yarn.lock b/fda-ui/yarn.lock index 2234f23e7e5db1962fa38e113cc512dce5a95e54..5fbbde314c9d3ac7290605df747fc9407b6535e5 100644 --- a/fda-ui/yarn.lock +++ b/fda-ui/yarn.lock @@ -5728,6 +5728,15 @@ fromentries@^1.2.0: resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== +fs-extra@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"