Skip to content

Commit

Permalink
Merge pull request #477 from edmcouncil/476-strapi-based-auth-feature
Browse files Browse the repository at this point in the history
Strapi based auth feature
  • Loading branch information
mereolog authored Aug 9, 2024
2 parents 313a7be + 11ba613 commit 72731c4
Show file tree
Hide file tree
Showing 37 changed files with 2,019 additions and 160 deletions.
2 changes: 2 additions & 0 deletions general/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ The following values can be defined in `variables`:

- `jenkinsJobUrl` - used to group versions based on Jenkins jobs. DEFAULT: `null`, EXAMPLE: `https://jenkins.edmcouncil.org/job/idmp/`

- `authEnabled` - used to enable authorization feature, login and register functionality will be enabled when value is set to `true`.

## Build and run frontend

- create directory for frontend application instance
Expand Down
169 changes: 120 additions & 49 deletions general/api/ontology.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,50 @@
import axios from 'axios';
import {
useAuthStore,
useOntologyStore,
useConfigurationStore,
useToastStore
} from '#imports';
export const axiosClient = axios.create();

axiosClient.interceptors.request.use((config) => {
const authStore = useAuthStore();
const configStore = useConfigurationStore();

const currentOrigin = window.location.origin;
const requestUrl = new URL(config.url, currentOrigin);

if (
configStore.config.authEnabled === 'true' &&
authStore.jwt &&
!config.noAuth &&
requestUrl.origin === currentOrigin
) {
config.headers.Authorization = `Bearer ${authStore.jwt}`;
}

return config;
});

axiosClient.interceptors.response.use(
(response) => response,
(error) => {
const toastStore = useToastStore();
const authStore = useAuthStore();
const ontologyStore = useOntologyStore();

if (error.response && error.response.status === 401) {
toastStore.addToast('Session expired. Please log in again.');
authStore.clear();
}
if (error.response && error.response.status === 403) {
ontologyStore.unauthorizedError = true;
}

return Promise.reject(error);
}
);

function ServerError(message, status) {
this.message = message;
this.status = status;
Expand All @@ -10,59 +57,83 @@ const parseServerError = (response) => {
return response;
};

const getEntity = (domain) =>
fetch(domain, {
method: 'GET',
headers: { Accept: 'application/json' }
}).then(parseServerError);
const getEntity = (domain, config = {}) =>
axiosClient
.get(domain, {
...config,
headers: { Accept: 'application/json', ...config.headers }
})
.then(parseServerError)
.then((response) => response.data);

const getModules = (domain) =>
fetch(domain, {
method: 'GET',
headers: { Accept: 'application/json' }
}).then(parseServerError);
const getModules = (domain, config = {}) =>
axiosClient
.get(domain, {
...config,
headers: { Accept: 'application/json', ...config.headers }
})
.then(parseServerError)
.then((response) => response.data);

const getOntologyVersions = (domain) =>
fetch(domain, {
method: 'GET',
headers: { Accept: 'application/json' }
}).then(parseServerError);
const getOntologyVersions = (domain, config = {}) =>
axiosClient
.get(domain, {
...config,
headers: { Accept: 'application/json', ...config.headers }
})
.then(parseServerError)
.then((response) => response.data);

const getJenkinsJobs = (domain) =>
fetch(domain, {
method: 'GET',
headers: { Accept: 'application/json' }
}).then(parseServerError);

const getFindSearch = (domain) =>
fetch(domain, {
method: 'GET',
headers: { Accept: 'application/json' }
}).then(parseServerError);

const getFindProperties = (domain) =>
fetch(domain, {
method: 'GET',
headers: { Accept: 'application/json' }
}).then(parseServerError);

const getStats = (domain) =>
fetch(domain, {
method: 'GET',
headers: { Accept: 'application/json' }
}).then(parseServerError);

const getMissingImports = (domain) =>
fetch(domain, {
method: 'GET',
headers: { Accept: 'application/json' }
}).then(parseServerError);

const getDescribeIntegration = (domain) =>
fetch(domain, {
method: 'GET',
headers: { Accept: 'application/rdf+xml' }
}).then(parseServerError);
axiosClient
.get(domain, { noAuth: true, headers: { Accept: 'application/json' } })
.then(parseServerError)
.then((response) => response.data);

const getFindSearch = (domain, config = {}) =>
axiosClient
.get(domain, {
...config,
headers: { Accept: 'application/json', ...config.headers }
})
.then(parseServerError)
.then((response) => response.data);

const getFindProperties = (domain, config = {}) =>
axiosClient
.get(domain, {
...config,
headers: { Accept: 'application/json', ...config.headers }
})
.then(parseServerError)
.then((response) => response.data);

const getStats = (domain, config = {}) =>
axiosClient
.get(domain, {
...config,
headers: { Accept: 'application/json', ...config.headers }
})
.then(parseServerError)
.then((response) => response.data);

const getMissingImports = (domain, config = {}) =>
axiosClient
.get(domain, {
...config,
headers: { Accept: 'application/json', ...config.headers }
})
.then(parseServerError)
.then((response) => response.data);

const getDescribeIntegration = (domain, config = {}) =>
axiosClient
.get(domain, {
...config,
headers: { Accept: 'application/rdf+xml', ...config.headers }
})
.then(parseServerError)
.then((response) => response.data);

export {
getEntity,
Expand Down
1 change: 1 addition & 0 deletions general/api/strapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ export async function getAppConfigurationData(runtimeConfig) {
data.uriSpace = response.data.attributes.uriSpace;
data.ontologyRepositoryUrl = response.data.attributes.ontologyRepositoryUrl;
data.jenkinsJobUrl = response.data.attributes.jenkinsJobUrl;
data.authEnabled = response.data.attributes.authEnabled;

// overwrite with 'variables' data
const { variables } = response.data.attributes;
Expand Down
5 changes: 5 additions & 0 deletions general/assets/icons/user.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
152 changes: 152 additions & 0 deletions general/assets/scss/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ body.modal-open {
}
&:focus {
background: $normal-button-focus-bg;
color: rgba(255, 255, 255, 0.9);
box-shadow: rgba(0, 0, 0, 0.4) 0px 0px 0px 4px;
}
&:active {
Expand Down Expand Up @@ -651,3 +652,154 @@ a.deprecated {
a.deprecated:hover {
color: #ec241d !important;
}

.modal-card {
.modal-error {
color: #ec241d;
}

.modal-form {
display: flex;
flex-direction: column;

.muted-link {
cursor: pointer;
align-self: flex-end;
color: rgba(0, 0, 0, 0.6);

&:focus-visible {
box-shadow: $form-focus-shadow;
}

&:active {
filter: none;
box-shadow: none;
}
}

.normal-button {
width: fit-content;
}

.alert {
color: rgba(0, 0, 0, 0.8);
font-style: normal;
font-weight: normal;
font-size: 14px;
line-height: 20px;
letter-spacing: 0.01em;
border: none;
border-radius: 2px;
margin-top: 20px;
padding: 5px 15px 5px 15px;
background-color: #ec241d;
}
}
}

.modal.login-modal,
.modal.recover-modal,
.modal.reset-modal,
.modal.confirmEmail-modal,
.modal.register-modal {
.modal-header {
position: relative;
box-shadow: 0px 5px 20px -5px rgba(8, 84, 150, 0.15);
border: none;
padding: 15px 40px;

justify-content: space-between;

.close-btn {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 24px;
height: 30px;
padding: 0;
margin-left: 20px;

&::before {
content: '';
background-image: url('../../assets/icons/close.svg');
background-repeat: no-repeat;
background-size: 24px 24px;
width: 24px;
height: 24px;
}
}

.return-btn {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
width: 24px;
height: 30px;
padding: 0;
margin-right: 20px;

&::before {
content: '';
background-image: url('../../assets/icons/return-arrow.svg');
background-repeat: no-repeat;
background-size: 24px 24px;
width: 24px;
height: 24px;
}
}

.left {
display: flex;
align-items: center;
}

h5.modal-title {
font-style: normal;
font-weight: bold;
font-size: 18px;
line-height: 30px;
color: #000000;

padding: 0;
margin: 0;
position: relative;
}
}
.modal-content {
border-radius: 2px;
border: none;
background: white;
height: 100%;
}
.modal-body {
padding: 30px 40px;
height: 100%;
position: relative;

a {
color: rgba(0, 0, 0, 0.8);
text-decoration: none;

&:hover {
color: $link-hover-color;
}

&:active {
color: $link-active-color;
}
}
}
.modal-footer {
border: none;
box-shadow: 0px -5px 20px -5px rgba(8, 84, 150, 0.15);
padding: 18px 30px;

justify-content: space-between;

.normal-button.small {
margin-bottom: 0 !important;
}
}
}
Loading

0 comments on commit 72731c4

Please sign in to comment.