Updated front-end to follow updated APIs.
This commit is contained in:
parent
67504d0883
commit
1134eef3ad
|
@ -44,9 +44,9 @@ public class GymService {
|
|||
query.orderBy(criteriaBuilder.desc(root.get("createdAt")));
|
||||
query.distinct(true);
|
||||
|
||||
// TODO: Filter to only verified submissions.
|
||||
return PredicateBuilder.and(criteriaBuilder)
|
||||
.with(criteriaBuilder.equal(root.get("gym"), gym))
|
||||
.with(criteriaBuilder.isTrue(root.get("complete")))
|
||||
.build();
|
||||
}, PageRequest.of(0, 10))
|
||||
.map(ExerciseSubmissionResponse::new)
|
||||
|
|
|
@ -111,9 +111,7 @@ module.exports = configure(function (ctx) {
|
|||
// directives: [],
|
||||
|
||||
// Quasar plugins
|
||||
plugins: [
|
||||
'Notify'
|
||||
],
|
||||
plugins: ['Notify'],
|
||||
},
|
||||
|
||||
// animations: 'all', // --- includes all animations
|
||||
|
|
|
@ -41,30 +41,49 @@ class AuthModule {
|
|||
clearTimeout(this.tokenRefreshTimer);
|
||||
}
|
||||
|
||||
public async register(payload: UserCreationPayload) {
|
||||
public async register(payload: UserCreationPayload): Promise<User> {
|
||||
const response = await api.post('/auth/register', payload);
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
public async activateUser(code: string): Promise<User> {
|
||||
const response = await api.post('/auth/activate', {code: code});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
private async fetchNewToken(credentials: TokenCredentials): Promise<string> {
|
||||
public async activateUser(code: string): Promise<User> {
|
||||
const response = await api.post('/auth/activate', { code: code });
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async fetchNewToken(credentials: TokenCredentials): Promise<string> {
|
||||
const response = await api.post('/auth/token', credentials);
|
||||
return response.data.token;
|
||||
}
|
||||
|
||||
private async refreshToken(authStore: AuthStoreType) {
|
||||
public async refreshToken(authStore: AuthStoreType) {
|
||||
const response = await api.get('/auth/token', authStore.axiosConfig);
|
||||
authStore.token = response.data.token;
|
||||
}
|
||||
|
||||
private async fetchMyUser(authStore: AuthStoreType): Promise<User> {
|
||||
public async fetchMyUser(authStore: AuthStoreType): Promise<User> {
|
||||
const response = await api.get('/auth/me', authStore.axiosConfig);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async updatePassword(newPassword: string, authStore: AuthStoreType) {
|
||||
await api.post(
|
||||
'/auth/me/password',
|
||||
{ newPassword: newPassword },
|
||||
authStore.axiosConfig
|
||||
);
|
||||
}
|
||||
|
||||
public async generatePasswordResetCode(email: string) {
|
||||
await api.get('/auth/reset-password', { params: { email: email } });
|
||||
}
|
||||
|
||||
public async resetPassword(resetCode: string, newPassword: string) {
|
||||
await api.post('/auth/reset-password', {
|
||||
code: resetCode,
|
||||
newPassword: newPassword,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default AuthModule;
|
||||
|
|
|
@ -13,7 +13,7 @@ export interface ExerciseSubmissionPayload {
|
|||
weight: number;
|
||||
weightUnit: string;
|
||||
reps: number;
|
||||
videoId: number;
|
||||
videoFileId: string;
|
||||
}
|
||||
|
||||
export interface ExerciseSubmission {
|
||||
|
@ -21,7 +21,7 @@ export interface ExerciseSubmission {
|
|||
createdAt: string;
|
||||
gym: SimpleGym;
|
||||
exercise: Exercise;
|
||||
status: ExerciseSubmissionStatus;
|
||||
videoFileId: string;
|
||||
submitterName: string;
|
||||
rawWeight: number;
|
||||
weightUnit: string;
|
||||
|
@ -29,14 +29,6 @@ export interface ExerciseSubmission {
|
|||
reps: number;
|
||||
}
|
||||
|
||||
export enum ExerciseSubmissionStatus {
|
||||
WAITING = 'WAITING',
|
||||
PROCESSING = 'PROCESSING',
|
||||
FAILED = 'FAILED',
|
||||
COMPLETED = 'COMPLETED',
|
||||
VERIFIED = 'VERIFIED',
|
||||
}
|
||||
|
||||
class SubmissionsModule {
|
||||
public async getSubmission(
|
||||
submissionId: string
|
||||
|
@ -45,16 +37,6 @@ class SubmissionsModule {
|
|||
return response.data;
|
||||
}
|
||||
|
||||
public getSubmissionVideoUrl(submission: ExerciseSubmission): string | null {
|
||||
if (
|
||||
submission.status !== ExerciseSubmissionStatus.COMPLETED &&
|
||||
submission.status !== ExerciseSubmissionStatus.VERIFIED
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return BASE_URL + `/submissions/${submission.id}/video`;
|
||||
}
|
||||
|
||||
public async createSubmission(
|
||||
gym: GymRoutable,
|
||||
payload: ExerciseSubmissionPayload
|
||||
|
@ -63,49 +45,6 @@ class SubmissionsModule {
|
|||
const response = await api.post(`/gyms/${gymId}/submissions`, payload);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async uploadVideoFile(gym: GymRoutable, file: File): Promise<number> {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const gymId = getGymCompoundId(gym);
|
||||
const response = await api.post(
|
||||
`/gyms/${gymId}/submissions/upload`,
|
||||
formData,
|
||||
{
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}
|
||||
);
|
||||
return response.data.id as number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronous method that waits until a submission is done processing.
|
||||
* @param submissionId The submission's id.
|
||||
*/
|
||||
public async waitUntilSubmissionProcessed(
|
||||
submissionId: string
|
||||
): Promise<ExerciseSubmission> {
|
||||
let failureCount = 0;
|
||||
let attemptCount = 0;
|
||||
while (failureCount < 5 && attemptCount < 60) {
|
||||
await sleep(1000);
|
||||
attemptCount++;
|
||||
try {
|
||||
const response = await this.getSubmission(submissionId);
|
||||
failureCount = 0;
|
||||
if (
|
||||
response.status !== ExerciseSubmissionStatus.WAITING &&
|
||||
response.status !== ExerciseSubmissionStatus.PROCESSING
|
||||
) {
|
||||
return response;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
failureCount++;
|
||||
}
|
||||
}
|
||||
throw new Error('Failed to wait for submission to complete.');
|
||||
}
|
||||
}
|
||||
|
||||
export default SubmissionsModule;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {boot} from 'quasar/wrappers';
|
||||
import {createI18n} from 'vue-i18n';
|
||||
import { boot } from 'quasar/wrappers';
|
||||
import { createI18n } from 'vue-i18n';
|
||||
|
||||
import messages from 'src/i18n';
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<script setup lang="ts">
|
||||
import { useAuthStore } from 'stores/auth-store';
|
||||
import api from 'src/api/main';
|
||||
import {useRoute, useRouter} from 'vue-router';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const route = useRoute();
|
||||
|
@ -39,8 +39,8 @@ async function goToLoginPage() {
|
|||
await router.push({
|
||||
path: '/login',
|
||||
query: {
|
||||
next: encodeURIComponent(route.path)
|
||||
}
|
||||
next: encodeURIComponent(route.path),
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<q-card>
|
||||
<q-card-section class="text-center">
|
||||
<video
|
||||
:src="api.gyms.submissions.getSubmissionVideoUrl(submission)"
|
||||
:src="getFileUrl(submission.videoFileId)"
|
||||
width="600"
|
||||
loop
|
||||
controls
|
||||
|
@ -30,6 +30,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ExerciseSubmission } from 'src/api/main/submission';
|
||||
import api from 'src/api/main';
|
||||
import { getFileUrl } from 'src/api/cdn';
|
||||
|
||||
interface Props {
|
||||
submission: ExerciseSubmission;
|
||||
|
|
|
@ -25,7 +25,7 @@ const i18n = useI18n({ useScope: 'global' });
|
|||
const localeOptions = [
|
||||
{ value: 'en-US', label: 'English' },
|
||||
{ value: 'nl-NL', label: 'Nederlands' },
|
||||
{ value: 'de', label: 'Deutsch' }
|
||||
{ value: 'de', label: 'Deutsch' },
|
||||
];
|
||||
</script>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ export default {
|
|||
leaderboard: 'Bestenliste',
|
||||
homePage: {
|
||||
overview: 'Überblick über dieses Fitnessstudio:',
|
||||
recentLifts: 'Letzten Aufzüge'
|
||||
recentLifts: 'Letzten Aufzüge',
|
||||
},
|
||||
submitPage: {
|
||||
name: 'Dein Name',
|
||||
|
@ -24,5 +24,4 @@ export default {
|
|||
submit: 'Einreichen',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -9,14 +9,14 @@ export default {
|
|||
email: 'Email',
|
||||
password: 'Password',
|
||||
register: 'Register',
|
||||
error: 'An error occurred.'
|
||||
error: 'An error occurred.',
|
||||
},
|
||||
loginPage: {
|
||||
title: 'Login to Gymboard',
|
||||
email: 'Email',
|
||||
password: 'Password',
|
||||
logIn: 'Log in',
|
||||
createAccount: 'Create an account'
|
||||
createAccount: 'Create an account',
|
||||
},
|
||||
indexPage: {
|
||||
searchHint: 'Search for a Gym',
|
||||
|
@ -41,6 +41,6 @@ export default {
|
|||
},
|
||||
accountMenuItem: {
|
||||
logIn: 'Login',
|
||||
logOut: 'Log out'
|
||||
}
|
||||
logOut: 'Log out',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -5,5 +5,5 @@ import de from './de';
|
|||
export default {
|
||||
'en-US': enUS,
|
||||
'nl-NL': nlNL,
|
||||
'de': de,
|
||||
de: de,
|
||||
};
|
||||
|
|
|
@ -9,14 +9,14 @@ export default {
|
|||
email: 'E-mail',
|
||||
password: 'Wachtwoord',
|
||||
register: 'Registreren',
|
||||
error: 'Er is een fout opgetreden.'
|
||||
error: 'Er is een fout opgetreden.',
|
||||
},
|
||||
loginPage: {
|
||||
title: 'Inloggen bij Gymboard',
|
||||
email: 'E-mail',
|
||||
password: 'Wachtwoord',
|
||||
logIn: 'Inloggen',
|
||||
createAccount: 'Account aanmaken'
|
||||
createAccount: 'Account aanmaken',
|
||||
},
|
||||
indexPage: {
|
||||
searchHint: 'Zoek een sportschool',
|
||||
|
@ -41,6 +41,6 @@ export default {
|
|||
},
|
||||
accountMenuItem: {
|
||||
logIn: 'Inloggen',
|
||||
logOut: 'Uitloggen'
|
||||
}
|
||||
logOut: 'Uitloggen',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
<StandardCenteredPage>
|
||||
<h3 class="text-center">About Gymboard</h3>
|
||||
<p>
|
||||
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Error fugit quia laboriosam eaque? Deserunt, accusantium dicta assumenda debitis incidunt eius provident magnam, est quasi officia voluptas, nam neque omnis reiciendis.
|
||||
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Error fugit quia
|
||||
laboriosam eaque? Deserunt, accusantium dicta assumenda debitis incidunt
|
||||
eius provident magnam, est quasi officia voluptas, nam neque omnis
|
||||
reiciendis.
|
||||
</p>
|
||||
</StandardCenteredPage>
|
||||
</template>
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
<template>
|
||||
<div
|
||||
class="fullscreen text-center q-pa-md flex flex-center"
|
||||
>
|
||||
<div class="fullscreen text-center q-pa-md flex flex-center">
|
||||
<div>
|
||||
<div style="font-size: 30vh">404</div>
|
||||
|
||||
<div class="text-h2" style="opacity: 0.4">Page not found.</div>
|
||||
|
||||
<q-btn
|
||||
class="q-mt-xl"
|
||||
unelevated
|
||||
to="/"
|
||||
label="Go Home"
|
||||
no-caps
|
||||
/>
|
||||
<q-btn class="q-mt-xl" unelevated to="/" label="Go Home" no-caps />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<StandardCenteredPage>
|
||||
<h3>Testing Page</h3>
|
||||
<p>
|
||||
Use this page to test new functionality, before adding it to the main app.
|
||||
This page should be hidden on production.
|
||||
Use this page to test new functionality, before adding it to the main
|
||||
app. This page should be hidden on production.
|
||||
</p>
|
||||
<div style="border: 3px solid red">
|
||||
<h4>Auth Test</h4>
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import StandardCenteredPage from 'components/StandardCenteredPage.vue';
|
||||
import {onMounted, ref} from 'vue';
|
||||
import {useRoute, useRouter} from 'vue-router';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import api from 'src/api/main';
|
||||
import {sleep} from 'src/utils';
|
||||
import {useI18n} from 'vue-i18n';
|
||||
import { sleep } from 'src/utils';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
@ -35,6 +35,4 @@ onMounted(async () => {
|
|||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
|
|
@ -28,11 +28,20 @@
|
|||
</q-input>
|
||||
</div>
|
||||
<div class="row">
|
||||
<q-btn type="submit" :label="$t('loginPage.logIn')" color="primary" class="q-mt-md col-12" no-caps/>
|
||||
<q-btn
|
||||
type="submit"
|
||||
:label="$t('loginPage.logIn')"
|
||||
color="primary"
|
||||
class="q-mt-md col-12"
|
||||
no-caps
|
||||
/>
|
||||
</div>
|
||||
<div class="row">
|
||||
<router-link
|
||||
:to="{ path: '/register', query: route.query.next ? { next: route.query.next } : {} }"
|
||||
:to="{
|
||||
path: '/register',
|
||||
query: route.query.next ? { next: route.query.next } : {},
|
||||
}"
|
||||
class="q-mt-md text-primary text-center col-12"
|
||||
>
|
||||
{{ $t('loginPage.createAccount') }}
|
||||
|
@ -46,10 +55,10 @@
|
|||
<script setup lang="ts">
|
||||
import StandardCenteredPage from 'components/StandardCenteredPage.vue';
|
||||
import SlimForm from 'components/SlimForm.vue';
|
||||
import {ref} from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import api from 'src/api/main';
|
||||
import {useAuthStore} from 'stores/auth-store';
|
||||
import {useRoute, useRouter} from 'vue-router';
|
||||
import { useAuthStore } from 'stores/auth-store';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const router = useRouter();
|
||||
|
@ -57,14 +66,16 @@ const route = useRoute();
|
|||
|
||||
const loginModel = ref({
|
||||
email: '',
|
||||
password: ''
|
||||
password: '',
|
||||
});
|
||||
const passwordVisible = ref(false);
|
||||
|
||||
async function tryLogin() {
|
||||
try {
|
||||
await api.auth.login(authStore, loginModel.value);
|
||||
const dest = route.query.next ? decodeURIComponent(route.query.next as string) : '/';
|
||||
const dest = route.query.next
|
||||
? decodeURIComponent(route.query.next as string)
|
||||
: '/';
|
||||
await router.push(dest);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
@ -77,6 +88,4 @@ function resetLogin() {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
|
|
@ -53,17 +53,17 @@
|
|||
import SlimForm from 'components/SlimForm.vue';
|
||||
import StandardCenteredPage from 'components/StandardCenteredPage.vue';
|
||||
import api from 'src/api/main';
|
||||
import {useRouter} from 'vue-router';
|
||||
import {ref} from 'vue';
|
||||
import {useQuasar} from 'quasar';
|
||||
import {useI18n} from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ref } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const registerModel = ref({
|
||||
name: '',
|
||||
email: '',
|
||||
password: ''
|
||||
password: '',
|
||||
});
|
||||
const passwordVisible = ref(false);
|
||||
|
||||
|
@ -77,7 +77,7 @@ async function tryRegister() {
|
|||
} catch (error) {
|
||||
quasar.notify({
|
||||
message: t('registerPage.error'),
|
||||
type: 'negative'
|
||||
type: 'negative',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,4 @@ function resetForm() {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
|
|
@ -10,6 +10,4 @@
|
|||
import StandardCenteredPage from 'components/StandardCenteredPage.vue';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
|
|
@ -69,7 +69,6 @@ onMounted(async () => {
|
|||
function initMap() {
|
||||
if (!gym.value) return;
|
||||
const g: Gym = gym.value;
|
||||
console.log(mapContainer);
|
||||
|
||||
const tiles = new TileLayer(TILE_URL, {
|
||||
attribution: ATTRIBUTION,
|
||||
|
|
|
@ -100,6 +100,7 @@ import { Gym } from 'src/api/main/gyms';
|
|||
import { Exercise } from 'src/api/main/exercises';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { sleep } from 'src/utils';
|
||||
import { uploadVideoToCDN, VideoProcessingStatus, waitUntilVideoProcessingComplete } from 'src/api/cdn';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
|
@ -117,7 +118,7 @@ let submissionModel = ref({
|
|||
weight: 100,
|
||||
weightUnit: 'Kg',
|
||||
reps: 1,
|
||||
videoId: -1,
|
||||
videoFileId: '',
|
||||
videoFile: null,
|
||||
date: new Date().toLocaleDateString('en-CA'),
|
||||
});
|
||||
|
@ -159,10 +160,7 @@ async function onSubmitted() {
|
|||
try {
|
||||
infoMessage.value = 'Uploading video...';
|
||||
await sleep(1000);
|
||||
submissionModel.value.videoId = await api.gyms.submissions.uploadVideoFile(
|
||||
gym.value,
|
||||
selectedVideoFile.value
|
||||
);
|
||||
submissionModel.value.videoFileId = await uploadVideoToCDN(selectedVideoFile.value);
|
||||
infoMessage.value = 'Creating submission...';
|
||||
await sleep(1000);
|
||||
const submission = await api.gyms.submissions.createSubmission(
|
||||
|
@ -170,11 +168,14 @@ async function onSubmitted() {
|
|||
submissionModel.value
|
||||
);
|
||||
infoMessage.value = 'Submission processing...';
|
||||
const completedSubmission =
|
||||
await api.gyms.submissions.waitUntilSubmissionProcessed(submission.id);
|
||||
console.log(completedSubmission);
|
||||
const finalStatus = await waitUntilVideoProcessingComplete(submission.videoFileId);
|
||||
if (finalStatus === VideoProcessingStatus.COMPLETED) {
|
||||
infoMessage.value = 'Submission complete!';
|
||||
await sleep(1000);
|
||||
await router.push(getGymRoute(gym.value));
|
||||
} else {
|
||||
infoMessage.value = 'Submission processing failed. Please try again later.';
|
||||
}
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import GymHomePage from 'pages/gym/GymHomePage.vue';
|
|||
import GymLeaderboardsPage from 'pages/gym/GymLeaderboardsPage.vue';
|
||||
import TestingPage from 'pages/TestingPage.vue';
|
||||
import LoginPage from 'pages/auth/LoginPage.vue';
|
||||
import RegisterPage from "pages/auth/RegisterPage.vue";
|
||||
import RegistrationSuccessPage from "pages/auth/RegistrationSuccessPage.vue";
|
||||
import ActivationPage from "pages/auth/ActivationPage.vue";
|
||||
import RegisterPage from 'pages/auth/RegisterPage.vue';
|
||||
import RegistrationSuccessPage from 'pages/auth/RegistrationSuccessPage.vue';
|
||||
import ActivationPage from 'pages/auth/ActivationPage.vue';
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
// Auth-related pages, which live outside the main layout.
|
||||
|
@ -35,7 +35,7 @@ const routes: RouteRecordRaw[] = [
|
|||
{ path: 'leaderboard', component: GymLeaderboardsPage },
|
||||
],
|
||||
},
|
||||
{ path: 'about', component: AboutPage }
|
||||
{ path: 'about', component: AboutPage },
|
||||
],
|
||||
},
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@ import nl.andrewlalis.gymboardcdn.util.ULID;
|
|||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
|
@ -18,24 +19,17 @@ public class Config {
|
|||
@Value("${app.api-origin}")
|
||||
private String apiOrigin;
|
||||
|
||||
/**
|
||||
* Defines the CORS configuration for this API, which is to say that we
|
||||
* allow cross-origin requests ONLY from the web app for the vast majority
|
||||
* of endpoints.
|
||||
* @return The CORS configuration source.
|
||||
*/
|
||||
@Bean
|
||||
@Order(1)
|
||||
public CorsConfigurationSource corsConfigurationSource() {
|
||||
public CorsFilter corsFilter() {
|
||||
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
final CorsConfiguration config = new CorsConfiguration();
|
||||
config.setAllowCredentials(true);
|
||||
config.addAllowedOriginPattern(webOrigin);
|
||||
config.addAllowedOriginPattern(apiOrigin);
|
||||
config.addAllowedHeader("*");
|
||||
config.addAllowedMethod("*");
|
||||
config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
|
||||
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
return source;
|
||||
return new CorsFilter(source);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
Loading…
Reference in New Issue