2 Commits

Author SHA1 Message Date
3cb12dab4f feat: created signature of all api functions
All checks were successful
Format / formatting (push) Successful in 8s
CI / build (push) Successful in 11s
2025-02-18 10:50:21 +01:00
0a9d83655f feat: query to database from and unaut endpoint
All checks were successful
Format / formatting (push) Successful in 9s
CI / build (push) Successful in 12s
2025-02-13 21:57:41 +01:00
30 changed files with 343 additions and 272 deletions

View File

@ -0,0 +1,78 @@
package enseirb.myinpulse.api;
import enseirb.myinpulse.api.datatypes.Project;
import enseirb.myinpulse.api.datatypes.ProjectDecision;
import enseirb.myinpulse.api.datatypes.Report;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
@SpringBootApplication
@RestController
public class AdminApi {
/**
* TODO
*
* @return a list of all project managed by the current admin user
*/
@GetMapping("/admin/projects")
public void getProjects() {}
/**
* TODO: Why in admin instead of shared ?
*
* @return a list of upcoming appointments for the current user
*/
@GetMapping("/admin/appointments/upcoming")
public void getUpcomingAppointments() {}
/**
* TODO
*
* @return a list of current unvalidated projects, waiting to be accepted
*/
@GetMapping("/admin/projects/pending")
public void getPendingProjects() {}
/**
* TODO
*
* <p>Endpoint used to make a decision about a project.
*
* @return the status code of the request
*/
@PostMapping("/admin/projects/decision")
public void validateProject(@RequestBody ProjectDecision decision) {}
/**
* TODO
*
* <p>Endpoint used to manually add a project by an admin
*
* @return the status code of the request
*/
@PostMapping("/admin/project/add")
public void addNewProject(@RequestBody Project project) {}
/**
* TODO: shouldn't it be an UPDATE request ?
*
* <p>Endpoint used to add a new report to an appointment
*
* @return the status code of the request
*/
@PostMapping("/admin/appoitements/report/{appointmentId}")
public void createAppointmentReport(
@PathVariable String appointmentId, @RequestBody Report report) {}
/**
* TODO: Shouldn't a project be kept in history ? 2 different endpoints ?
*
* <p>Endpoint used to completely remove a project.
*
* @return the status code of the request
*/
@DeleteMapping("/admin/projects/remove/{projectId}")
public void deleteProject(@PathVariable String projectId) {}
}

View File

@ -0,0 +1,51 @@
package enseirb.myinpulse.api;
import enseirb.myinpulse.api.datatypes.LCSection;
import enseirb.myinpulse.api.datatypes.Project;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
@SpringBootApplication
@RestController
public class EntrepreneurApi {
/**
* TODO
*
* <p>Endpoint used to update a LC section.
*
* @return status code
*/
@PutMapping("/entrepreneur/lcsection/modify/{sectionId}")
public void editLCSection(@PathVariable String sectionId, @RequestBody LCSection section) {}
/**
* TODO
*
* <p>Endpoint used to delete a LC section
*
* @return status code
*/
@DeleteMapping("/entrepreneur/lcsection/remove/{sectionId}")
public void removeLCSection(@PathVariable String sectionId) {}
/**
* TODO
*
* <p>Endpoint used to create a new LC section
*
* @return status code
*/
@PostMapping("/entrepreneur/lcsection/add/{sectionId}")
public void addLCSection(@PathVariable String sectionId, @RequestBody LCSection section) {}
/**
* TODO
*
* <p>Endpoint used to request the creation of a new project
*
* @return status code
*/
@PostMapping("/entrepreneur/project/request")
public void requestNewProject(@RequestBody Project project) {}
}

View File

@ -1,30 +1,20 @@
package enseirb.myinpulse.api; package enseirb.myinpulse.api;
import enseirb.myinpulse.postgres_db.controller.ComptesRendusController;
import enseirb.myinpulse.postgres_db.model.ComptesRendus;
import enseirb.myinpulse.postgres_db.repository.ComptesRendusRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.security.Principal;
import javax.management.relation.RoleNotFoundException;
@SpringBootApplication @SpringBootApplication
@RestController @RestController
public class GetUserInfo { public class GetUserInfo {
// TODO: understand how to get data
@GetMapping("/getUserInfo")
public Object user(Principal principal) {
System.out.println("GetUserInfo + " + principal);
System.out.println(SecurityContextHolder.getContext().getAuthentication());
return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS})
@GetMapping("/unauth/random") @GetMapping("/unauth/random")
public boolean rand(@RequestHeader("Authorization") String token) throws RoleNotFoundException { public boolean rand() {
System.err.println(token);
return Math.random() > 0.5; return Math.random() > 0.5;
} }
@ -37,4 +27,11 @@ public class GetUserInfo {
public boolean rand3() { public boolean rand3() {
return Math.random() > 0.5; return Math.random() > 0.5;
} }
@Autowired
@GetMapping("/unauth/dev")
public ComptesRendus testApi(ComptesRendusRepository repository) {
ComptesRendusController comptesRendusController = new ComptesRendusController(repository);
return comptesRendusController.getComptesRendusById((long) 1);
}
} }

View File

@ -0,0 +1,78 @@
package enseirb.myinpulse.api;
import enseirb.myinpulse.api.datatypes.Appointment;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
@SpringBootApplication
@RestController
public class SharedApi {
/**
* TODO: It does not looks like a good id to have the title and the date in the url. What even
* TODO: is the title btw ? if this is the LC section, wouldn't it be better to use an ID ?
* TODO: choose return type, cf comment in LCSection
*
* <p>Endpoint used to get the data inside the lean canvas
*
* @return a list of lean canvas sections
*/
@GetMapping("/shared/project/lcsection/{projectId}/{title}/{date}")
public void getLCSection(
@PathVariable("projectId") String projectId,
@PathVariable("title") String title,
@PathVariable("date") String date) {}
/**
* TODO
*
* <p>Endpoint used to get entrepreneurs details
*
* @return a list of all entrepreneurs in a project
*/
@GetMapping("/shared/entrepreneurs/{projectId}")
public void getEntrepreneursByProjectId(@PathVariable int projectId) {}
/**
* TODO: is it really useful for the admin ? We can already get all the project of the current
* administrator.
*
* <p>Endpoint used to get the administrator of a project.
*
* @return a list of all project managed by the current admin user
*/
@GetMapping("/shared/projects/admin/{projectId}")
public void getAdminByProjectId(@PathVariable int projectId) {}
/**
* TODO: Should it really be all appointments? all future appointments ? a flag to choose \\
* TODO: between both ?
*
* <p>Endpoint used to get all appointments of a single project.
*
* @return a list of all appointments.
*/
@GetMapping("/shared/projects/appointments/{projectId}")
public void getAppointmentsByProjectId(@PathVariable int projectId) {}
/**
* TODO: Shouldn't the last two parameters be swapped ?
*
* <p>Endpoint used to generate a PDF report
*
* @return a PDF file? TODO: how does that works ?
*/
@GetMapping("/shared/projects/appointments/report/{appointmentId}")
public void getPDFReport(@PathVariable int appointmentId) {}
/**
* TODO
*
* <p>
*
* @return a list of all project managed by the current admin user
*/
@PostMapping("/shared/appointment/request")
public void createAppointmentRequest(@RequestBody Appointment appointment) {}
}

View File

@ -0,0 +1,8 @@
package enseirb.myinpulse.api.datatypes;
public class Appointment {
int validated;
int[] akserId;
int[] destId;
String date; // TODO: date type ?
}

View File

@ -0,0 +1,7 @@
package enseirb.myinpulse.api.datatypes;
// TODO: is this redundant with the Section class from the database ?
// TODO: In the one hand it represent the same data, and on the other it should be much lighter.
// TODO: btw why does a LC section have an administrator ?
public class LCSection {}

View File

@ -0,0 +1,7 @@
package enseirb.myinpulse.api.datatypes;
public class Project {
int projectId;
String projectName;
String projectDescription;
}

View File

@ -0,0 +1,7 @@
package enseirb.myinpulse.api.datatypes;
public class ProjectDecision {
int projectId;
int adminId;
int isAccepted;
}

View File

@ -0,0 +1,6 @@
package enseirb.myinpulse.api.datatypes;
public class Report {
int projectId;
String reportContent;
}

View File

@ -1,7 +0,0 @@
package enseirb.myinpulse.exceptions;
public class RoleNotFoudException extends RuntimeException {
public RoleNotFoudException(String message) {
super(message);
}
}

View File

@ -1,7 +0,0 @@
package enseirb.myinpulse.exceptions;
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String message) {
super(message);
}
}

View File

@ -3,7 +3,6 @@ package enseirb.myinpulse.postgres_db.controller;
import enseirb.myinpulse.postgres_db.model.ComptesRendus; import enseirb.myinpulse.postgres_db.model.ComptesRendus;
import enseirb.myinpulse.postgres_db.repository.ComptesRendusRepository; import enseirb.myinpulse.postgres_db.repository.ComptesRendusRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ResponseStatusException;
@ -13,7 +12,11 @@ import java.util.Optional;
@RestController @RestController
public class ComptesRendusController { public class ComptesRendusController {
@Autowired ComptesRendusRepository comptesRendusRepository; private final ComptesRendusRepository comptesRendusRepository;
public ComptesRendusController(ComptesRendusRepository comptesRendusRepository) {
this.comptesRendusRepository = comptesRendusRepository;
}
@GetMapping("/ComptesRendus") @GetMapping("/ComptesRendus")
@ResponseBody @ResponseBody
@ -44,6 +47,6 @@ public class ComptesRendusController {
if (contenu_compte_rendu != null) { if (contenu_compte_rendu != null) {
compteRendu.get().setContenu_compte_rendu(contenu_compte_rendu); compteRendu.get().setContenu_compte_rendu(contenu_compte_rendu);
} }
return this.comptesRendusRepository.save(compteRendu.get()); return compteRendu.get();
} }
} }

View File

@ -53,6 +53,6 @@ public class EntrepreneursController {
if (status_snee != null) { if (status_snee != null) {
entrepreneur.get().setStatus_snee(status_snee); entrepreneur.get().setStatus_snee(status_snee);
} }
return this.entrepreneursRepository.save(entrepreneur.get()); return entrepreneur.get();
} }
} }

View File

@ -59,6 +59,6 @@ public class ProjetsController {
if (status_projet != null) { if (status_projet != null) {
projet.get().setStatus_projet(status_projet); projet.get().setStatus_projet(status_projet);
} }
return this.projetsRepository.save(projet.get()); return projet.get();
} }
} }

View File

@ -2,14 +2,16 @@ package enseirb.myinpulse.postgres_db.controller;
import enseirb.myinpulse.postgres_db.model.RendezVous; import enseirb.myinpulse.postgres_db.model.RendezVous;
import enseirb.myinpulse.postgres_db.repository.RendezVousRepository; import enseirb.myinpulse.postgres_db.repository.RendezVousRepository;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ResponseStatusException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Optional;
@RestController @RestController
public class RendezVousController { public class RendezVousController {
@ -39,8 +41,8 @@ public class RendezVousController {
public RendezVous updateRendezVous( public RendezVous updateRendezVous(
@PathVariable Long id, @PathVariable Long id,
LocalDate date_rdv, LocalDate date_rdv,
LocalTime heure_rdv, LocalDateTime heure_rdv,
LocalTime duree_rdv, LocalDateTime duree_rdv,
String lieu_rdv, String lieu_rdv,
String sujet_rdv) { String sujet_rdv) {
Optional<RendezVous> rendezVous = this.rendezVousRepository.findById(id); Optional<RendezVous> rendezVous = this.rendezVousRepository.findById(id);
@ -62,6 +64,6 @@ public class RendezVousController {
if (sujet_rdv != null) { if (sujet_rdv != null) {
rendezVous.get().setSujet_rdv(sujet_rdv); rendezVous.get().setSujet_rdv(sujet_rdv);
} }
return this.rendezVousRepository.save(rendezVous.get()); return rendezVous.get();
} }
} }

View File

@ -55,6 +55,6 @@ public class SectionsController {
if (date_modification != null) { if (date_modification != null) {
section.get().setDate_modification(date_modification); section.get().setDate_modification(date_modification);
} }
return this.sectionsRepository.save(section.get()); return section.get();
} }
} }

View File

@ -62,6 +62,6 @@ public class UtilisateursController {
if (numero_telephone != null) { if (numero_telephone != null) {
utilisateur.get().setNumero_telephone(numero_telephone); utilisateur.get().setNumero_telephone(numero_telephone);
} }
return this.utilisateursRepository.save(utilisateur.get()); return utilisateur.get();
} }
} }

View File

@ -9,7 +9,7 @@ import java.util.List;
@Entity @Entity
@Table(name = "administrateurs") @Table(name = "administrateurs")
@PrimaryKeyJoinColumn(name = "id_administrateur", referencedColumnName = "id_utilisateur") @PrimaryKeyJoinColumn(name = "id_administrateur")
public class Administrateurs extends Utilisateurs { public class Administrateurs extends Utilisateurs {
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)

View File

@ -6,7 +6,7 @@ import jakarta.persistence.Table;
@Entity @Entity
@Table(name = "entrepreneurs") @Table(name = "entrepreneurs")
@PrimaryKeyJoinColumn(name = "id_entrepreneur", referencedColumnName = "id_utilisateur") @PrimaryKeyJoinColumn(name = "id_entrepreneur")
public class Entrepreneurs extends Utilisateurs { public class Entrepreneurs extends Utilisateurs {
@Column(length = 255) @Column(length = 255)

View File

@ -4,7 +4,7 @@ import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -36,8 +36,8 @@ public class RendezVous {
private Long id_rdv; private Long id_rdv;
private LocalDate date_rdv; private LocalDate date_rdv;
private LocalTime heure_rdv; private LocalDateTime heure_rdv;
private LocalTime duree_rdv; private LocalDateTime duree_rdv;
@Column(length = 255) @Column(length = 255)
private String lieu_rdv; private String lieu_rdv;
@ -49,8 +49,8 @@ public class RendezVous {
public RendezVous( public RendezVous(
Long id_rdv, Long id_rdv,
LocalDate date_rdv, LocalDate date_rdv,
LocalTime heure_rdv, LocalDateTime heure_rdv,
LocalTime duree_rdv, LocalDateTime duree_rdv,
String lieu_rdv, String lieu_rdv,
String sujet_rdv) { String sujet_rdv) {
this.id_rdv = id_rdv; this.id_rdv = id_rdv;
@ -77,19 +77,19 @@ public class RendezVous {
this.date_rdv = date_rdv; this.date_rdv = date_rdv;
} }
public LocalTime getHeure_rdv() { public LocalDateTime getHeure_rdv() {
return heure_rdv; return heure_rdv;
} }
public void setHeure_rdv(LocalTime heure_rdv) { public void setHeure_rdv(LocalDateTime heure_rdv) {
this.heure_rdv = heure_rdv; this.heure_rdv = heure_rdv;
} }
public LocalTime getDuree_rdv() { public LocalDateTime getDuree_rdv() {
return duree_rdv; return duree_rdv;
} }
public void setDuree_rdv(LocalTime duree_rdv) { public void setDuree_rdv(LocalDateTime duree_rdv) {
this.duree_rdv = duree_rdv; this.duree_rdv = duree_rdv;
} }

View File

@ -25,7 +25,7 @@ public class Utilisateurs {
@Column(length = 255) @Column(length = 255)
private String mail_secondaire; private String mail_secondaire;
@Column(length = 20) @Column(length = 15)
private String numero_telephone; private String numero_telephone;
public Utilisateurs() {} public Utilisateurs() {}

View File

@ -1,7 +1,3 @@
/*
* Source: https://github.com/ChristianHuff-DEV/secure-spring-rest-api-using-keycloak/blob/main/src/main/java/io/betweendata/RestApi/security/oauth2/KeycloakJwtRolesConverter.java
* edited by Pierre Tellier
*/
package enseirb.myinpulse.security; package enseirb.myinpulse.security;
import static java.util.stream.Collectors.toSet; import static java.util.stream.Collectors.toSet;
@ -42,7 +38,7 @@ public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthent
source, source,
Stream.concat( Stream.concat(
new JwtGrantedAuthoritiesConverter().convert(source).stream(), new JwtGrantedAuthoritiesConverter().convert(source).stream(),
tokenRolesExtractor(source).stream()) TEMPORARNAME(source).stream())
.collect(toSet())); .collect(toSet()));
} }
@ -50,7 +46,7 @@ public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthent
* Extracts the realm and resource level roles from a JWT token distinguishing between them * Extracts the realm and resource level roles from a JWT token distinguishing between them
* using prefixes. * using prefixes.
*/ */
public Collection<GrantedAuthority> tokenRolesExtractor(Jwt jwt) { public Collection<GrantedAuthority> TEMPORARNAME(Jwt jwt) {
// Collection that will hold the extracted roles // Collection that will hold the extracted roles
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>(); Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();

View File

@ -1,135 +0,0 @@
package enseirb.myinpulse.utils.keycloak;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import enseirb.myinpulse.exceptions.UserNotFoundException;
import enseirb.myinpulse.utils.keycloak.datatypes.RoleRepresentation;
import enseirb.myinpulse.utils.keycloak.datatypes.UserRepresentation;
import org.springframework.web.client.RestClient;
import javax.management.relation.RoleNotFoundException;
public class KeycloakApi {
static final String keycloakUrl;
static final String realmName;
static {
if (System.getenv("VITE_KEYCLOAK_URL") == null) {
System.exit(-1);
}
keycloakUrl = System.getenv("VITE_KEYCLOAK_URL");
}
static {
if (System.getenv("VITE_KEYCLOAK_REALM") == null) {
System.exit(-1);
}
realmName = System.getenv("VITE_KEYCLOAK_REALM");
}
/**
* Uses Keycloak API to retrieve a role representation of a role by its name
*
* @param roleName name of the role
* @param bearer authorization header used by the client to authenticate to keycloak
*/
public static RoleRepresentation getRoleRepresentationByName(String roleName, String bearer)
throws RoleNotFoundException {
RoleRepresentation[] response =
RestClient.builder()
.baseUrl(keycloakUrl)
.defaultHeader("Authorization", bearer)
.build()
.get()
.uri("/admin/realms/{realmName}/roles/{roleName}", realmName, roleName)
.retrieve()
.body(RoleRepresentation[].class);
if (response == null || response.length == 0) {
throw new RoleNotFoundException("Role not found");
}
return response[0];
}
/**
* Use keycloak API to to retreive a userID via his name or email.
*
* @param username username or mail of the user
* @param bearer bearer of the user, allowing access to database
* @return the userid, as a String
* @throws UserNotFoundException
*/
public static String getUserIdByName(String username, String bearer)
throws UserNotFoundException {
UserRepresentation[] response =
RestClient.builder()
.baseUrl(keycloakUrl)
.defaultHeader("Authorization", bearer)
.build()
.get()
.uri(
"/admin/realms/{realmName}/users?username={username}",
realmName,
username)
.retrieve()
.body(UserRepresentation[].class);
if (response == null || response.length == 0) {
throw new UserNotFoundException("User not found");
}
return response[0].id;
}
/**
* TODO: check for error
*
* <p>Set a keycloak role to a keycloak user.
*
* <p>Usual roles should be `MyINPulse-admin` and `MyINPulse-entrepreneur`
*
* @param username
* @param roleName
* @param bearer
* @throws RoleNotFoundException
* @throws UserNotFoundException
*/
public static void setRoleToUser(String username, String roleName, String bearer)
throws RoleNotFoundException, UserNotFoundException {
RoleRepresentation roleRepresentation = getRoleRepresentationByName(roleName, bearer);
String userId = getUserIdByName(username, bearer);
RestClient.builder()
.baseUrl(keycloakUrl)
.defaultHeader("Authorization", bearer)
.build()
.post()
.uri(
"/admin/realms/${realmName}/users/${userId}/role-mappings/realm",
realmName,
userId)
.body(roleRepresentation)
.contentType(APPLICATION_JSON)
.retrieve();
}
/**
* Delete a user from Keycloak database. TODO: check the bearer permission.
*
* @param username
* @param bearer
* @throws UserNotFoundException
*/
public static void deleteUser(String username, String bearer) throws UserNotFoundException {
String userId = getUserIdByName(username, bearer);
RestClient.builder()
.baseUrl(keycloakUrl)
.defaultHeader("Authorization", bearer)
.build()
.delete()
.uri("/admin/realms/${realmName}/users/${userId}", realmName, userId)
.retrieve();
}
}

View File

@ -1,7 +0,0 @@
package enseirb.myinpulse.utils.keycloak.datatypes;
public class RoleRepresentation {
public String id;
public String name;
public String description;
}

View File

@ -1,6 +0,0 @@
package enseirb.myinpulse.utils.keycloak.datatypes;
public class UserRepresentation {
public String id;
public String name;
}

View File

@ -1,5 +1,3 @@
TRUNCATE projets, utilisateurs, entrepreneurs, sections, rendez_vous, comptes_rendus CASCADE;
INSERT INTO projets (nom_projet, logo, date_creation, status_projet) INSERT INTO projets (nom_projet, logo, date_creation, status_projet)
VALUES ('Eau du robinet', decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'), TO_DATE('01-OCT-2023', 'DD-MON-YYYY'), VALUES ('Eau du robinet', decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'), TO_DATE('01-OCT-2023', 'DD-MON-YYYY'),
'En cours'), 'En cours'),
@ -9,49 +7,56 @@ VALUES ('Eau du robinet', decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'), TO_
('HDeirbMI', decode('ab548d6c1d595a2975e6476f544d14c55a', 'hex'), TO_DATE('07-DEC-2024', 'DD-MON-YYYY'), ('HDeirbMI', decode('ab548d6c1d595a2975e6476f544d14c55a', 'hex'), TO_DATE('07-DEC-2024', 'DD-MON-YYYY'),
'Lancement'); 'Lancement');
INSERT INTO utilisateurs (nom_utilisateur, prenom_utilisateur, mail_principal, mail_secondaire, numero_telephone) VALUES INSERT INTO utilisateurs (nom_utilisateur, prenom_utilisateur, mail_principal, mail_secondaire, numero_telephone)
('Dupont', 'Dupond', 'super@mail.fr', 'super2@mail.fr', '06 45 72 45 98'), VALUES ('Dupont', 'Dupond', 'super@mail.fr', 'super2@mail.fr', '06 45 72 45 98'),
('Martin', 'Matin', 'genial@mail.fr', 'genial2@mail.fr', '06 52 14 58 73'), ('Martin', 'Matin', 'genial@mail.fr', 'genial2@mail.fr', '06 52 14 58 73'),
('Charvet', 'Lautre', 'mieux@tmail.fr', 'mieux2@tmail.fr', '07 49 82 16 35'), ('Charvet', 'Lautre', 'mieux@tmail.fr', 'mieux2@tmail.fr', '07 49 82 16 35'),
('Leguez', 'Theo', 'bof@mesmails.fr', 'bof2@mesmails.fr', '+33 6 78 14 25 29'), ('Leguez', 'Theo', 'bof@mesmails.fr', 'bof2@mesmails.fr', '+33 6 78 14 25 29'),
('Kia', 'Bi', 'special@mail.fr', 'special2@mail.fr', '07 65 31 38 95'), ('Kia', 'Bi', 'special@mail.fr', 'special2@mail.fr', '07 65 31 38 95');
('Ducaillou', 'Pierre', 'maildefou@xyz.fr', 'maildefou2@xyz.fr', '06 54 78 12 62');
INSERT INTO entrepreneurs (ecole, filiere, status_snee)
VALUES ('ENSEIRB-MATMECA', 'INFO', TRUE),
('ENSC', 'Cognitique', TRUE),
('ENSEIRB-MATMECA', 'MATMECA', FALSE),
('SupOptique', 'Classique', TRUE),
('ENSEGID', 'Géoscience', FALSE),
('ENSMAC', 'Matériaux composites - Mécanique', FALSE);
INSERT INTO entrepreneurs (ecole, filiere, status_snee, id_entrepreneur) VALUES INSERT INTO sections (titre, contenu_section, date_modification)
('ENSEIRB-MATMECA', 'INFO', TRUE, 1), VALUES ("Problème", "les problèmes...", TO_DATE('15-JAN-2025', 'DD-MON-YYYY')),
('ENSC', 'Cognitique', TRUE, 2), ("Segment de client", "Le segment AB passant le client n°8 est de longueur 32mm.
('ENSEIRB-MATMECA', 'MATMECA', FALSE, 3), Le segment BC a quant à lui un longueur de 28mm. Quelle la longueur du segment AC ?",
('SupOptique', 'Classique', TRUE, 4), TO_DATE('12-OCT-2022', 'DD-MON-YYYY')),
('ENSEGID', 'Géoscience', FALSE, 5), ("Proposition de valeur unique", "'Son prix est de 2594€' 'Ah oui c'est unique en effet'",
('ENSMAC', 'Matériaux composites - Mécanique', FALSE, 6); TO_DATE('25-MAY-2024', 'DD-MON-YYYY')),
("Solution", "Un problème ? Une solution", TO_DATE('08-FEB-2024', 'DD-MON-YYYY')),
("Canaux", "Ici nous avons la Seine, là-bas le Rhin, oh et plus loin le canal de Suez",
TO_DATE('19-JUL-2023', 'DD-MON-YYYY')),
("Sources de revenus", "Y'en n'a pas on est pas payé. Enfin y'a du café quoi",
TO_DATE('12-JAN-2025', 'DD-MON-YYYY')),
("Structure des coûts", "'Ah oui là ça va faire au moins 1000€ par mois', Eirbware",
TO_DATE('06-FEB-2025', 'DD-MON-YYYY')),
("Indicateurs clés", "On apprend les clés comme des badges, ça se fait", TO_DATE('05-FEB-2025', 'DD-MON-YYYY')),
("Avantages concurrentiel", "On est meilleur", TO_DATE('23-APR-2024', 'DD-MON-YYYY'));
INSERT INTO sections (titre, contenu_section, date_modification) VALUES INSERT INTO rendez_vous (date_rdv, heure_rdv, duree_rdv, lieu_rdv, sujet_rdv)
('Problème', 'les problèmes...', TO_TIMESTAMP('15-JAN-2025 09:30:20', 'DD-MON-YYYY, HH24:MI:SS')), VALUES (TO_DATE('24-DEC-2023', 'DD-MON-YYYY'), '00:00:00', '00:37:53', "À la maison", "Ouvrir les cadeaux"),
('Segment de client', 'Le segment AB passant le client n°8 est de longueur 32mm. (TO_DATE('15-AUG-2024', 'DD-MON-YYYY'), '22:35:00', '00:12:36', "Sur les quais ou dans un champ probablement",
Le segment BC a quant à lui un longueur de 28mm. Quelle la longueur du segment AC ?', TO_TIMESTAMP('12-OCT-2022 17:47:38', 'DD-MON-YYYY, HH24:MI:SS')), "BOUM BOUM les feux d'artifices (on fête quoi déjà ?)"),
('Proposition de valeur unique', '''Son prix est de 2594€'' ''Ah oui c''est unique en effet', TO_TIMESTAMP('25-MAY-2024 11:12:04', 'DD-MON-YYYY, HH24:MI:SS')), (TO_DATE('29-FEB-2023', 'DD-MON-YYYY'), '14:20:00', '00:20:00', "Salle TD 15",
('Solution', 'Un problème ? Une solution', TO_TIMESTAMP('08-FEB-2024 10:17:53', 'DD-MON-YYYY, HH24:MI:SS')), "Ah mince c'est pas une année bissextile !"),
('Canaux', 'Ici nous avons la Seine, là-bas le Rhin, oh et plus loin le canal de Suez', TO_TIMESTAMP('19-JUL-2023 19:22:45', 'DD-MON-YYYY, HH24:MI:SS')), (TO_DATE('23-JAN-2024', 'DD-MON-YYYY'), '12:56:27', '11:03:33', "Là où le vent nous porte",
('Sources de revenus', 'Y''en n''a pas on est pas payé. Enfin y''a du café quoi', TO_TIMESTAMP('12-JAN-2025 11:40:26', 'DD-MON-YYYY, HH24:MI:SS')), "Journée la plus importante de l'année"),
('Structure des coûts', '''Ah oui là ça va faire au moins 1000€ par mois'', Eirbware', TO_TIMESTAMP('06-FEB-2025 13:04:06', 'DD-MON-YYYY, HH24:MI:SS')), (TO_DATE('25-AUG-2025', 'DD-MON-YYYY'), '00:09:00', '01:00:00', "Euh c'est par où l'amphi 56 ?",
('Indicateurs clés', 'On apprend les clés comme des badges, ça se fait', TO_TIMESTAMP('05-FEB-2025 12:42:38', 'DD-MON-YYYY, HH24:MI:SS')), "Rentrée scolaire (il fait trop froid c'est quoi ça on est en août)");
('Avantages concurrentiel', 'On est meilleur', TO_TIMESTAMP('23-APR-2024 16:24:02', 'DD-MON-YYYY, HH24:MI:SS'));
INSERT INTO rendez_vous (date_rdv, heure_rdv, duree_rdv, lieu_rdv, sujet_rdv) VALUES INSERT INTO comptes_rendus (contenu_compte_rendu)
(TO_DATE('24-DEC-2023', 'DD-MON-YYYY'), '00:00:00', '00:37:53', 'À la maison', 'Ouvrir les cadeaux'), VALUES ("Ah oui ça c'est super, ah ouais j'aime bien, bien vu de penser à ça"),
(TO_DATE('15-AUG-2024', 'DD-MON-YYYY'), '22:35:00', '00:12:36', 'Sur les quais ou dans un champ probablement', 'BOUM BOUM les feux d''artifices (on fête quoi déjà ?)'), ("Bonne réunion"),
(TO_DATE('28-FEB-2023', 'DD-MON-YYYY'), '14:20:00', '00:20:00', 'Salle TD 15', 'Ah mince c''est pas une année bissextile !'), ("Ouais, j'ai rien compris mais niquel on fait comme vous avez dit"),
(TO_DATE('23-JAN-2024', 'DD-MON-YYYY'), '12:56:27', '11:03:33', 'Là où le vent nous porte', 'Journée la plus importante de l''année'), ("Non non ça va pas du tout ce que tu me proposes, faut tout refaire"),
(TO_DATE('25-AUG-2025', 'DD-MON-YYYY'), '00:09:00', '01:00:00', 'Euh c''est par où l''amphi 56 ?', 'Rentrée scolaire (il fait trop froid c''est quoi ça on est en août)'); ("Réponse de la DSI : non"),
("Trop dommage qu'Apple ait sorti leur logiciel avant nous, on avait la même idée et tout on aurait tellement pu leur faire de la concurrence");
INSERT INTO comptes_rendus (contenu_compte_rendu) VALUES
('Ah oui ça c''est super, ah ouais j''aime bien, bien vu de penser à ça'),
('Bonne réunion'),
('Ouais, j''ai rien compris mais niquel on fait comme vous avez dit'),
('Non non ça va pas du tout ce que tu me proposes, faut tout refaire'),
('Réponse de la DSI : non'),
('Trop dommage qu''Apple ait sorti leur logiciel avant nous, on avait la même idée et tout on aurait tellement pu leur faire de la concurrence');

View File

@ -1 +0,0 @@
DROP TABLE IF EXISTS administrateurs, projets, utilisateurs, entrepreneurs, sections, rendez_vous, comptes_rendus, concerner CASCADE;

View File

@ -25,8 +25,9 @@ nom_utilisateur VARCHAR(255) ,
prenom_utilisateur VARCHAR(255), prenom_utilisateur VARCHAR(255),
mail_principal VARCHAR(255), mail_principal VARCHAR(255),
mail_secondaire VARCHAR(255), mail_secondaire VARCHAR(255),
numero_telephone VARCHAR(20) , numero_telephone VARCHAR(15),
CONSTRAINT pk_utilisateur PRIMARY KEY (id_utilisateur) ); CONSTRAINT pk_utilisateur PRIMARY KEY (id_utilisateur)
);
CREATE TABLE entrepreneurs CREATE TABLE entrepreneurs
( (

View File

@ -14,8 +14,7 @@ axiosInstance.interceptors.response.use(
async (error) => { async (error) => {
const originalRequest = error.config; const originalRequest = error.config;
if ( if (
((error.response && error.response.status === 401) || error.response.status === 401 &&
error.code == "ERR_NETWORK") &&
!originalRequest._retry && !originalRequest._retry &&
store.authenticated store.authenticated
) { ) {

View File

@ -1,9 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { store } from "../main.ts"; import { store } from "../main.ts";
import { callApi } from "@/services/api.ts"; import { callApi } from "@/services/api.ts";
import { ref } from "vue";
const CustomRequest = ref("");
</script> </script>
<template> <template>
@ -53,19 +50,11 @@ const CustomRequest = ref("");
<tr> <tr>
<td>Unauth API call</td> <td>Unauth API call</td>
<td> <td>
<button @click="callApi('random3')">call</button> <button @click="callApi('unauth/dev')">call</button>
</td> </td>
<td>res</td> <td>res</td>
<td id="3"></td> <td id="3"></td>
</tr> </tr>
<tr>
<td>
<input v-model="CustomRequest" placeholder="edit me" />
</td>
<td>
<button @click="callApi(CustomRequest)">call</button>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</template> </template>