diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..1bcdeae --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,29 @@ +build-vue: + image: docker:latest + stage: build + services: + - docker:dind + script: + - cd frontend + - docker build --pull -t vue . + rules: + - if: $CI_MERGE_REQUEST_ID + +build-backend: + image: docker:latest + stage: build + services: + - docker:dind + script: + - cd backend + - docker build --pull -t backend . + rules: + - if: $CI_MERGE_REQUEST_ID + +build-android: + image: debian + stage: build + script: + - echo "To be done" + rules: + - if: $CI_MERGE_REQUEST_ID diff --git a/backend/build.gradle b/backend/build.gradle index 7811350..499d544 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -1,26 +1,32 @@ plugins { - id 'org.springframework.boot' version '2.2.6.RELEASE' - id 'io.spring.dependency-management' version '1.0.9.RELEASE' - id "io.freefair.lombok" version "5.0.0-rc6" - id 'java' + id "org.springframework.boot" version "2.2.6.RELEASE" + id "io.spring.dependency-management" version "1.0.9.RELEASE" + id "io.freefair.lombok" version "5.0.0" + id "java" } -group = 'de.hft' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '11' +group = "de.hft" +version = "0.0.1-SNAPSHOT" +sourceCompatibility = "11" repositories { mavenCentral() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-rest' implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-actuator' + + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' implementation 'org.mariadb.jdbc:mariadb-java-client' + implementation "org.springframework.boot:spring-boot-starter-security" + implementation "com.auth0:java-jwt:3.10.2" + runtimeOnly 'com.h2database:h2' + testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } diff --git a/backend/src/main/java/de/hft/geotime/GeotimeApplication.java b/backend/src/main/java/de/hft/geotime/GeotimeApplication.java index f2563ba..859b276 100644 --- a/backend/src/main/java/de/hft/geotime/GeotimeApplication.java +++ b/backend/src/main/java/de/hft/geotime/GeotimeApplication.java @@ -2,7 +2,9 @@ package de.hft.geotime; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @SpringBootApplication @ComponentScan(basePackages = "de.hft") @@ -12,4 +14,9 @@ public class GeotimeApplication { SpringApplication.run(GeotimeApplication.class, args); } + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + } diff --git a/backend/src/main/java/de/hft/geotime/record/RecordRepository.java b/backend/src/main/java/de/hft/geotime/record/RecordRepository.java new file mode 100644 index 0000000..22b7906 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/record/RecordRepository.java @@ -0,0 +1,7 @@ +package de.hft.geotime.record; + +import org.springframework.data.repository.CrudRepository; + +public interface RecordRepository extends CrudRepository { + +} diff --git a/backend/src/main/java/de/hft/geotime/record/RecordType.java b/backend/src/main/java/de/hft/geotime/record/RecordType.java new file mode 100644 index 0000000..0adab48 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/record/RecordType.java @@ -0,0 +1,8 @@ +package de.hft.geotime.record; + +public enum RecordType { + + BREAK, + PAID + +} diff --git a/backend/src/main/java/de/hft/geotime/record/TimeRecord.java b/backend/src/main/java/de/hft/geotime/record/TimeRecord.java new file mode 100644 index 0000000..3280d37 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/record/TimeRecord.java @@ -0,0 +1,29 @@ +package de.hft.geotime.record; + +import de.hft.geotime.timetrackaccount.TimetrackAccount; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import java.time.Duration; +import java.util.Date; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class TimeRecord { + + @Id + private long id; + @OneToOne + private TimetrackAccount account; + private Date startdate; + private Date enddate; + private Duration time; + private RecordType type; + +} diff --git a/backend/src/main/java/de/hft/geotime/role/Role.java b/backend/src/main/java/de/hft/geotime/role/Role.java new file mode 100644 index 0000000..7b319b7 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/role/Role.java @@ -0,0 +1,24 @@ +package de.hft.geotime.role; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Role { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + private String name; + // TODO: Permission List + +} diff --git a/backend/src/main/java/de/hft/geotime/role/RoleRepository.java b/backend/src/main/java/de/hft/geotime/role/RoleRepository.java new file mode 100644 index 0000000..7e26fa7 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/role/RoleRepository.java @@ -0,0 +1,7 @@ +package de.hft.geotime.role; + +import org.springframework.data.repository.CrudRepository; + +public interface RoleRepository extends CrudRepository { + +} diff --git a/backend/src/main/java/de/hft/geotime/security/JWTAuthenticationFilter.java b/backend/src/main/java/de/hft/geotime/security/JWTAuthenticationFilter.java new file mode 100644 index 0000000..f111c1f --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/security/JWTAuthenticationFilter.java @@ -0,0 +1,60 @@ +package de.hft.geotime.security; + +import com.auth0.jwt.JWT; +import com.fasterxml.jackson.databind.ObjectMapper; +import de.hft.geotime.user.TimetrackUser; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import javax.servlet.FilterChain; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; + +import static com.auth0.jwt.algorithms.Algorithm.HMAC512; +import static de.hft.geotime.security.SecurityConstants.*; + +public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { + private final AuthenticationManager authenticationManager; + + public JWTAuthenticationFilter(AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } + + @Override + public Authentication attemptAuthentication( + HttpServletRequest req, + HttpServletResponse res) throws AuthenticationException { + try { + TimetrackUser creds = new ObjectMapper().readValue(req.getInputStream(), TimetrackUser.class); + return authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + creds.getUsername(), + creds.getPassword(), + new ArrayList<>() + ) + ); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + protected void successfulAuthentication( + HttpServletRequest req, + HttpServletResponse res, + FilterChain chain, + Authentication auth) { + String token = JWT.create() + .withSubject(((User) auth.getPrincipal()).getUsername()) + .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) + .sign(HMAC512(SECRET.getBytes())); + res.addHeader(HEADER_STRING, TOKEN_PREFIX + token); + } +} \ No newline at end of file diff --git a/backend/src/main/java/de/hft/geotime/security/JWTAuthorizationFilter.java b/backend/src/main/java/de/hft/geotime/security/JWTAuthorizationFilter.java new file mode 100644 index 0000000..7a9525f --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/security/JWTAuthorizationFilter.java @@ -0,0 +1,56 @@ +package de.hft.geotime.security; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; + +import static de.hft.geotime.security.SecurityConstants.*; + +public class JWTAuthorizationFilter extends BasicAuthenticationFilter { + + public JWTAuthorizationFilter(AuthenticationManager authManager) { + super(authManager); + } + + @Override + protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException { + String header = req.getHeader(HEADER_STRING); + + if (header == null || !header.startsWith(TOKEN_PREFIX)) { + chain.doFilter(req, res); + return; + } + + UsernamePasswordAuthenticationToken authentication = getAuthentication(req); + + SecurityContextHolder.getContext().setAuthentication(authentication); + chain.doFilter(req, res); + } + + private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) { + String token = request.getHeader(HEADER_STRING); + if (token != null) { + // parse the token. + String user = JWT.require(Algorithm.HMAC512(SECRET.getBytes())) + .build() + .verify(token.replace(TOKEN_PREFIX, "")) + .getSubject(); + + if (user != null) { + return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>()); + } + return null; + } + return null; + } +} \ No newline at end of file diff --git a/backend/src/main/java/de/hft/geotime/security/SecurityConstants.java b/backend/src/main/java/de/hft/geotime/security/SecurityConstants.java new file mode 100644 index 0000000..d568748 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/security/SecurityConstants.java @@ -0,0 +1,9 @@ +package de.hft.geotime.security; + +public class SecurityConstants { + public static final String SECRET = "SecretKeyToGenJWTs"; + public static final long EXPIRATION_TIME = 864_000_000; // 10 days + public static final String TOKEN_PREFIX = "Bearer "; + public static final String HEADER_STRING = "Authorization"; + public static final String SIGN_UP_URL = "/user/sign-up"; +} \ No newline at end of file diff --git a/backend/src/main/java/de/hft/geotime/security/WebSecurity.java b/backend/src/main/java/de/hft/geotime/security/WebSecurity.java new file mode 100644 index 0000000..63c3213 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/security/WebSecurity.java @@ -0,0 +1,51 @@ +package de.hft.geotime.security; + +import de.hft.geotime.user.UserDetailsServiceImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import static de.hft.geotime.security.SecurityConstants.SIGN_UP_URL; + +@EnableWebSecurity +public class WebSecurity extends WebSecurityConfigurerAdapter { + private final UserDetailsServiceImpl userDetailsService; + private final BCryptPasswordEncoder bCryptPasswordEncoder; + + public WebSecurity(UserDetailsServiceImpl userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) { + this.userDetailsService = userDetailsService; + this.bCryptPasswordEncoder = bCryptPasswordEncoder; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.cors().and().csrf().disable().authorizeRequests() + .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll() + .anyRequest().authenticated() + .and() + .addFilter(new JWTAuthenticationFilter(authenticationManager())) + .addFilter(new JWTAuthorizationFilter(authenticationManager())) + // this disables session creation on Spring Security + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder); + } + + @Bean + CorsConfigurationSource corsConfigurationSource() { + final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); + return source; + } +} \ No newline at end of file diff --git a/backend/src/main/java/de/hft/geotime/timetrackaccount/TimetrackAccount.java b/backend/src/main/java/de/hft/geotime/timetrackaccount/TimetrackAccount.java new file mode 100644 index 0000000..772e6ec --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/timetrackaccount/TimetrackAccount.java @@ -0,0 +1,25 @@ +package de.hft.geotime.timetrackaccount; + +import de.hft.geotime.user.TimetrackUser; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class TimetrackAccount { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + @OneToOne + private TimetrackUser timetrackUser; + private double revenue; + private String name; + private String description; + +} diff --git a/backend/src/main/java/de/hft/geotime/timetrackaccount/TimetrackAccountRepository.java b/backend/src/main/java/de/hft/geotime/timetrackaccount/TimetrackAccountRepository.java new file mode 100644 index 0000000..38bbc91 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/timetrackaccount/TimetrackAccountRepository.java @@ -0,0 +1,7 @@ +package de.hft.geotime.timetrackaccount; + +import org.springframework.data.repository.CrudRepository; + +public interface TimetrackAccountRepository extends CrudRepository { + +} diff --git a/backend/src/main/java/de/hft/geotime/user/TimetrackUser.java b/backend/src/main/java/de/hft/geotime/user/TimetrackUser.java new file mode 100644 index 0000000..aebd202 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/user/TimetrackUser.java @@ -0,0 +1,32 @@ +package de.hft.geotime.user; + +import de.hft.geotime.role.Role; +import de.hft.geotime.timetrackaccount.TimetrackAccount; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.UniqueElements; + +import javax.persistence.*; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class TimetrackUser { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + @UniqueElements + private String username; + private String password; + private String firstname; + private String lastname; + @OneToOne + private Role role; + @OneToMany + private List timetrackAccounts; + +} diff --git a/backend/src/main/java/de/hft/geotime/user/TimetrackUserRepository.java b/backend/src/main/java/de/hft/geotime/user/TimetrackUserRepository.java new file mode 100644 index 0000000..5eb7367 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/user/TimetrackUserRepository.java @@ -0,0 +1,11 @@ +package de.hft.geotime.user; + +import org.springframework.data.repository.CrudRepository; + +import javax.websocket.server.PathParam; + +public interface TimetrackUserRepository extends CrudRepository { + + TimetrackUser findFirstByUsername(@PathParam("username") String username); + +} diff --git a/backend/src/main/java/de/hft/geotime/user/User.java b/backend/src/main/java/de/hft/geotime/user/User.java deleted file mode 100644 index f697365..0000000 --- a/backend/src/main/java/de/hft/geotime/user/User.java +++ /dev/null @@ -1,30 +0,0 @@ -package de.hft.geotime.user; - -import lombok.Data; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -@Data -@Entity -public class User { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private long id; - private String username; - private String firstname; - private String lastname; - //TODO: roleid(FK) - //TODO: timetrackaccounts[List] - - protected User() { - } - - public User(String firstname, String lastname) { - this.firstname = firstname; - this.lastname = lastname; - } -} diff --git a/backend/src/main/java/de/hft/geotime/user/UserController.java b/backend/src/main/java/de/hft/geotime/user/UserController.java new file mode 100644 index 0000000..5d73f85 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/user/UserController.java @@ -0,0 +1,35 @@ +package de.hft.geotime.user; + +import org.springframework.security.core.Authentication; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; + +@RestController +@RequestMapping("/user") +public class UserController { + + private TimetrackUserRepository userRepository; + private BCryptPasswordEncoder bCryptPasswordEncoder; + + public UserController(TimetrackUserRepository userRepository, BCryptPasswordEncoder bCryptPasswordEncoder) { + this.userRepository = userRepository; + this.bCryptPasswordEncoder = bCryptPasswordEncoder; + } + + @GetMapping + public String getUsername(Authentication authentication) { + TimetrackUser timetrackUser = userRepository.findFirstByUsername(authentication.getName()); + return "Welcome back " + timetrackUser.getFirstname() + " " + timetrackUser.getLastname(); + } + + // TODO: implement register, maybe move to another class + @PostMapping("/sign-up") + public HashMap signUp(@RequestBody HashMap payload) { + return payload; + // user.setPassword(bCryptPasswordEncoder.encode(user.getPassword())); + // userRepository.save(user); + } + +} diff --git a/backend/src/main/java/de/hft/geotime/user/UserDetailsServiceImpl.java b/backend/src/main/java/de/hft/geotime/user/UserDetailsServiceImpl.java new file mode 100644 index 0000000..365b6f8 --- /dev/null +++ b/backend/src/main/java/de/hft/geotime/user/UserDetailsServiceImpl.java @@ -0,0 +1,29 @@ +package de.hft.geotime.user; + +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.Collections; + +@Service +public class UserDetailsServiceImpl implements UserDetailsService { + + private final TimetrackUserRepository userRepository; + + public UserDetailsServiceImpl(TimetrackUserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + TimetrackUser timetrackUser = userRepository.findFirstByUsername(username); + if (timetrackUser == null) { + throw new UsernameNotFoundException(username); + } + System.out.println("Loaded user " + timetrackUser.getFirstname() + " " + timetrackUser.getLastname()); + return new User(timetrackUser.getUsername(), timetrackUser.getPassword(), Collections.emptyList()); + } +} diff --git a/backend/src/main/java/de/hft/geotime/user/UserRepository.java b/backend/src/main/java/de/hft/geotime/user/UserRepository.java deleted file mode 100644 index 9b303ba..0000000 --- a/backend/src/main/java/de/hft/geotime/user/UserRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.hft.geotime.user; - -import org.springframework.data.repository.PagingAndSortingRepository; -import org.springframework.data.rest.core.annotation.RepositoryRestResource; - -import javax.websocket.server.PathParam; -import java.util.List; - -@RepositoryRestResource -public interface UserRepository extends PagingAndSortingRepository { - - List findByUsername(@PathParam("username") String username); - -} diff --git a/backend/src/main/resources/application-dev.properties b/backend/src/main/resources/application-dev.properties index e69de29..4497ed1 100644 --- a/backend/src/main/resources/application-dev.properties +++ b/backend/src/main/resources/application-dev.properties @@ -0,0 +1,7 @@ +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console \ No newline at end of file diff --git a/backend/src/main/resources/application-prod.properties b/backend/src/main/resources/application-prod.properties index 63f56f2..2ed9234 100644 --- a/backend/src/main/resources/application-prod.properties +++ b/backend/src/main/resources/application-prod.properties @@ -2,4 +2,5 @@ spring.jpa.hibernate.ddl-auto=update spring.datasource.url=jdbc:mariadb://db:3306/geotime spring.datasource.username=root spring.datasource.password=supersecure +spring.datasource.initialization-mode=always spring.datasource.driver-class-name=org.mariadb.jdbc.Driver \ No newline at end of file diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 1cf2a4f..fb71f70 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -1,5 +1,5 @@ server.port=80 -spring.data.rest.basePath=/api spring.datasource.hikari.initialization-fail-timeout=0 spring.datasource.hikari.max-lifetime=300000 +spring.jpa.show-sql=true spring.profiles.active=prod \ No newline at end of file diff --git a/backend/src/main/resources/data.sql b/backend/src/main/resources/data.sql new file mode 100644 index 0000000..861a41f --- /dev/null +++ b/backend/src/main/resources/data.sql @@ -0,0 +1,18 @@ +SET FOREIGN_KEY_CHECKS=0; + +DELETE FROM timetrack_user; +DELETE FROM role; + +INSERT INTO role (id, `name`) VALUES + (1, 'Admin'); + + /* password is the firstname in lowercase e.g. marcel or tobias + https://bcrypt-generator.com/ with 10 rounds + */ +INSERT INTO timetrack_user (id, firstname, lastname, password, username, role_id) VALUES + (1, 'Marcel', 'Schwarz' ,'$2y$10$pDBv7dEaAiNs5Kr1.8g4XuTFx48zGxJu77rei4TlO.sDOF2yHWxo.', 'scma', 1), + (2, 'Tobias', 'Wieck' ,'$2y$10$Fxj5cGrZblGKjIExvS/MquEE0lgyYo1ILxPgPR2vSiaaLKkqJ.C.u', 'wito', 1), + (3, 'Tim', 'Zieger' ,'$2y$10$pYGHZhoaelceImO7aIN4nOkWJBp.oqNGFYaRAonHkYF4u9ljqPelC', 'ziti', 1), + (4, 'Simon', 'Kellner' ,'$2y$10$Puzm/Nr/Dyq3nQxlkXGIfubS5JPtXJSOf2e6mrQ6HhVYQN9YiQQsC', 'kesi', 1); + +SET FOREIGN_KEY_CHECKS=1; \ No newline at end of file diff --git a/frontend/Dockerfile b/frontend/Dockerfile index db4139f..001a49e 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,5 +1,5 @@ # build stage -FROM node:12 as build-stage +FROM node:14 as build-stage WORKDIR /app COPY package*.json ./ RUN npm install diff --git a/frontend/src/components/layout/Header.vue b/frontend/src/components/layout/Header.vue index d5098bd..d3a527b 100644 --- a/frontend/src/components/layout/Header.vue +++ b/frontend/src/components/layout/Header.vue @@ -1,7 +1,7 @@