Skip to content

Commit

Permalink
convert loading with callbacks to react-router-loaders (...end)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminpochat committed Aug 19, 2024
1 parent b878d48 commit b744e6a
Show file tree
Hide file tree
Showing 31 changed files with 265 additions and 297 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ public StripePayment createPayment(Order order) throws StripeException {
.setApplicationFeeAmount(1L).build())
.setMode(SessionCreateParams.Mode.PAYMENT)
.setCustomerEmail(order.getCustomer().getUser().getEmail())
.setSuccessUrl(viandeEnDirectConfiguration.getCustomerFrontendUrl() + "/orders/" + order.getId() + "/payment")
.setCancelUrl(viandeEnDirectConfiguration.getCustomerFrontendUrl() + "/orders/" + order.getId() + "/payment")
.setSuccessUrl(viandeEnDirectConfiguration.getCustomerFrontendUrl() + "/order/" + order.getId() + "/payment")
.setCancelUrl(viandeEnDirectConfiguration.getCustomerFrontendUrl() + "/order/" + order.getId() + "/payment")
.setExpiresAt(Instant.now().plusSeconds(30 * 60).getEpochSecond())
.build();
RequestOptions requestOptions = RequestOptions.builder().setStripeAccount(getProducerStripeAccount(order).getStripeAccount().getStripeId()).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public StripePayment createPayment(Order order) throws StripeException {
SessionCreateParams params = builder
.setPaymentIntentData(SessionCreateParams.PaymentIntentData.builder().setTransferGroup(order.getId().toString()).build())
.setMode(SessionCreateParams.Mode.PAYMENT)
.setSuccessUrl(viandeendirectProducerFrontendUrl + "/orders/" + order.getId() + "/payment")
.setCancelUrl(viandeendirectProducerFrontendUrl + "/orders/" + order.getId() + "/payment")
.setSuccessUrl(viandeendirectProducerFrontendUrl + "/order/" + order.getId() + "/payment")
.setCancelUrl(viandeendirectProducerFrontendUrl + "/order/" + order.getId() + "/payment")
.build();
Session session = Session.create(params);
StripePayment stripePayment = new StripePayment();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import eu.viandeendirect.api.CustomersApiDelegate;
import eu.viandeendirect.model.Customer;
import eu.viandeendirect.model.User;
import eu.viandeendirect.security.specs.AuthenticationServiceSpecs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -41,13 +42,17 @@ public ResponseEntity<Customer> getCustomer(String email) {
if (producer.isPresent()) {
throw new ResponseStatusException(CONFLICT);
} else {
return new ResponseEntity<>(NO_CONTENT);
customer = new Customer();
var user = new User();
user.setEmail(email);
customer.setUser(user);
return new ResponseEntity<>(customer, OK);
}
}
if (!customer.getUser().getEmail().equals(email)) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
return new ResponseEntity<>(customer, HttpStatus.OK);
return new ResponseEntity<>(customer, OK);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void should_deserialize_the_checkout_session_from_event_data() throws SignatureV
"status": null
},
"billing_address_collection": null,
"cancel_url": "https://customer.sandbox.viandeendirect.eu/orders/14/paymentCancelled",
"cancel_url": "https://customer.sandbox.viandeendirect.eu/order/14/paymentCancelled",
"client_reference_id": null,
"client_secret": null,
"consent": null,
Expand Down Expand Up @@ -127,7 +127,7 @@ void should_deserialize_the_checkout_session_from_event_data() throws SignatureV
"status": "complete",
"submit_type": null,
"subscription": null,
"success_url": "https://customer.sandbox.viandeendirect.eu/orders/14/paymentSuccessful",
"success_url": "https://customer.sandbox.viandeendirect.eu/order/14/paymentSuccessful",
"total_details": {
"amount_discount": 0,
"amount_shipping": 0,
Expand Down
22 changes: 0 additions & 22 deletions frontend/app/src/api/ApiBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,4 @@ export class ApiBuilder {
return new DefaultApi(configuration)
}
}

/**
*
* @param {*} apiFunction
* @param {Keycloak} keycloak
*/
invokeAuthenticatedApi(apiFunction, keycloak) {
if(process.env.REACT_APP_MOCK_API) {
apiFunction()
} else {
keycloak.updateToken(30).then(function () {
apiFunction()
}).catch(function (error) {
console.log('Failed to refresh token');
console.log(error);
})
}
}

invokeAnonymousApi(apiFunction) {
apiFunction()
}
}
56 changes: 0 additions & 56 deletions frontend/app/src/api/ApiInvoker.ts

This file was deleted.

36 changes: 36 additions & 0 deletions frontend/app/src/authentication/service/AuthenticationService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import Keycloak from "keycloak-js"
import { ApiBuilder } from "../../api/ApiBuilder.ts"
import { Producer } from "@viandeendirect/api/dist/models/Producer"

export class AuthenticationService {
keycloak: Keycloak
Expand All @@ -11,6 +13,40 @@ export class AuthenticationService {
return (!!process.env.REACT_APP_MOCK_API) || (!!this.keycloak.authenticated)
}

async isAuthenticatedAsProducer(): Promise<boolean> {
if (this.isAuthenticated()) {
try {
const userEmail = this.getCurrentUserEmail()
const apiBuilder = new ApiBuilder()
const api = await apiBuilder.getAuthenticatedApi(this.keycloak)
await api.getProducer({'email': userEmail})
return true
} catch (error) {
if(error.response.status === 409) {
return false
}
}
}
return false
}

async isAuthenticatedAsCustomer(): Promise<boolean> {
if (this.isAuthenticated()) {
try {
const userEmail = this.getCurrentUserEmail()
const apiBuilder = new ApiBuilder()
const api = await apiBuilder.getAuthenticatedApi(this.keycloak)
await api.getCustomer({'email': userEmail})
return true
} catch (error) {
if(error.response.status === 409) {
return false
}
}
}
return false
}

getCurrentUserName(): string | undefined {
if(process.env.REACT_APP_MOCK_API) {
return "Utilisateur TEST"
Expand Down
34 changes: 20 additions & 14 deletions frontend/app/src/authentication/views/NotAuthorizedForCustomers.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import React from 'react'
import { Box, Toolbar, Typography, Button, ButtonGroup, AppBar, CssBaseline, IconButton } from '@mui/material'
import { useKeycloak } from '@react-keycloak/web'
import React from 'react'
import { useEffect, useState } from 'react'
import { UrlService } from '../../domains/commons/service/UrlService.ts'
import { Logout } from '@mui/icons-material'
import { Navigate, useLoaderData } from 'react-router-dom'
import { AuthenticationService } from '../service/AuthenticationService.ts'

export default function NotAuthorizedForCustomers() {

const urlService = new UrlService()
const [customerFrontendUrl, setCustomerFrontendUrl] = useState<String>()
const {keycloak} = useKeycloak()

useEffect(() => {
urlService.getCustomerFrontentUrl().then(setCustomerFrontendUrl)
})

const data = useLoaderData()
const authenticatedAsCustomer = data.authenticatedAsCustomer
const customerFrontendUrl = data.customerFrontendUrl

if (!authenticatedAsCustomer) {
return <Navigate to='/'/>
}

return <Box component="main" sx={{ flexGrow: 1, p: 3 }}>
<CssBaseline />
Expand All @@ -27,9 +29,6 @@ export default function NotAuthorizedForCustomers() {
<Typography variant="h5" component="div" sx={{ flexGrow: 1 }}>
Viande en direct
</Typography>
<IconButton onClick={keycloak.logout} color="inherit">
<Logout/>
</IconButton>
</Toolbar>
</AppBar>
<Toolbar/>
Expand All @@ -39,13 +38,20 @@ export default function NotAuthorizedForCustomers() {
<ButtonGroup>
<Button size="small" variant="outlined" onClick={() => {
keycloak.logout()
keycloak.login()
}}>
Changer de compte
Se déconnecter
</Button>
<Button size="small" variant="contained" onClick={() => window.open(customerFrontendUrl, '_self')}>
Accéder à l'espace client
</Button>
</ButtonGroup>
</Box>
}

export async function loadNotAuthorizedForCustomerData(keycloak) {
const authenticationService = new AuthenticationService(keycloak)
const authenticatedAsCustomer = await authenticationService.isAuthenticatedAsCustomer()
const urlService = new UrlService()
const customerFrontendUrl = await urlService.getCustomerFrontentUrl()
return {authenticatedAsCustomer: authenticatedAsCustomer, customerFrontendUrl: customerFrontendUrl}
}
74 changes: 48 additions & 26 deletions frontend/app/src/authentication/views/NotAuthorizedForProducers.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,56 @@
import { Box, Toolbar, Typography, Button, ButtonGroup } from '@mui/material'
import { useKeycloak } from '@react-keycloak/web'
import React from 'react'
import { useEffect, useState } from 'react'
import { Box, Toolbar, Typography, Button, ButtonGroup, CssBaseline, AppBar } from '@mui/material'
import { useKeycloak } from '@react-keycloak/web'
import { UrlService } from '../../domains/commons/service/UrlService.ts'
import { AuthenticationService } from '../service/AuthenticationService.ts'
import { Navigate, useLoaderData } from 'react-router-dom'

export default function NotAuthorizedForProducers() {

const urlService = new UrlService()
const [producerFrontendUrl, setProducerFrontendUrl] = useState<String>()
const {keycloak} = useKeycloak()

useEffect(() => {
urlService.getProducerFrontentUrl().then(setProducerFrontendUrl)
})
const { keycloak } = useKeycloak()
const data = useLoaderData()
const authenticatedAsProducer = data.authenticatedAsProducer
const producerFrontendUrl = data.producerFrontendUrl

if (!authenticatedAsProducer) {
return <Navigate to='/'/>
}

return <Box component="main" sx={{ flexGrow: 1, p: 3 }}>
<Toolbar />
<Typography>Vous êtes dans l'espace client de viandeendirect.eu</Typography>
<Typography>Votre compte est un compte producteur.</Typography>
<Typography>Il est impossible d'accéder à l'espace client avec un compte producteur</Typography>
<ButtonGroup>
<Button size="small" variant="outlined" onClick={() => {
keycloak.logout()
keycloak.login()
}}>
Changer de compte
</Button>
<Button size="small" variant="contained" onClick={() => window.open(producerFrontendUrl, '_self')}>
Accéder à l'espace producteur
</Button>
</ButtonGroup>
</Box>
<CssBaseline />
<AppBar
position="fixed"
sx={{
zIndex: (theme) => theme.zIndex.drawer + 1,
}}
>
<Toolbar>
<Typography variant="h5" component="div" sx={{ flexGrow: 1 }}>
Viande en direct
</Typography>
</Toolbar>
</AppBar>
<Toolbar/>
<Typography>Vous êtes dans l'espace client de viandeendirect.eu</Typography>
<Typography>Votre compte est un compte producteur.</Typography>
<Typography>Il est impossible d'accéder à l'espace client avec un compte producteur</Typography>
<ButtonGroup>
<Button size="small" variant="outlined" onClick={() => {
keycloak.logout()
}}>
Se déconnecter
</Button>
<Button size="small" variant="contained" onClick={() => window.open(producerFrontendUrl, '_self')}>
Accéder à l'espace producteur
</Button>
</ButtonGroup>
</Box>
}

export async function loadNotAuthorizedForProducerData(keycloak) {
const authenticationService = new AuthenticationService(keycloak)
const authenticatedAsProducer = await authenticationService.isAuthenticatedAsProducer()
const urlService = new UrlService()
const producerFrontendUrl = await urlService.getProducerFrontentUrl()
return {authenticatedAsProducer: authenticatedAsProducer, producerFrontendUrl: producerFrontendUrl}
}
30 changes: 1 addition & 29 deletions frontend/app/src/domains/commons/service/ProducerService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import Keycloak from "keycloak-js"
import {Producer} from "@viandeendirect/api/dist/models/Producer.js";
import { ApiInvoker } from "../../../api/ApiInvoker.ts";
import { AuthenticationService } from "../../../authentication/service/AuthenticationService.ts";
import { ApiBuilder } from "../../../api/ApiBuilder.ts";

Expand All @@ -15,34 +14,7 @@ export class ProducerService {
this.apiBuilder = new ApiBuilder();
}

loadProducer(setProducer, setUnauthorized = unauthorized => {}) {
if(!ProducerService.producer) {
const apiInvoker = new ApiInvoker()
const authenticationService = new AuthenticationService(this.keycloak)
apiInvoker.callApiAuthenticatedly(
this.keycloak,
api => api.getProducer,
{'email': authenticationService.getCurrentUserEmail()},
producer => {
ProducerService.producer = producer
ProducerService.unauthorized = false
setProducer(ProducerService.producer)
setUnauthorized(ProducerService.unauthorized)
},
error => {
console.error(error)
ProducerService.unauthorized = true
setProducer(ProducerService.producer)
setUnauthorized(ProducerService.unauthorized)
}
)
} else {
setProducer(ProducerService.producer)
setUnauthorized(ProducerService.unauthorized)
}
}

async asyncLoadProducer(): Promise<Producer> {
async loadProducer(): Promise<Producer> {
const api = await this.apiBuilder.getAuthenticatedApi(this.keycloak)
const authenticationService = new AuthenticationService(this.keycloak)
return await api.getProducer({'email': authenticationService.getCurrentUserEmail()})
Expand Down
Loading

0 comments on commit b744e6a

Please sign in to comment.