нужно добавить пользователю поля, а также изменить логику на страницах с действиями читателя и создателя
This commit is contained in:
parent
b3f98c6325
commit
864614acea
14
build.gradle
14
build.gradle
@ -16,22 +16,18 @@ jar {
|
||||
}
|
||||
dependencies {
|
||||
implementation(project(':front'))
|
||||
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
|
||||
implementation 'com.h2database:h2:2.1.210'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
implementation 'com.auth0:java-jwt:4.4.0'
|
||||
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
|
||||
|
||||
implementation 'org.hibernate.validator:hibernate-validator'
|
||||
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
|
||||
implementation 'org.webjars:bootstrap:5.1.3'
|
||||
implementation 'org.webjars:jquery:3.6.0'
|
||||
implementation 'org.webjars:font-awesome:6.1.0'
|
||||
|
||||
implementation 'com.h2database:h2:2.1.210'
|
||||
implementation 'org.hibernate.validator:hibernate-validator'
|
||||
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
//implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5'
|
||||
|
||||
|
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
274
data.trace.db
274
data.trace.db
@ -993,3 +993,277 @@ Caused by: org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikola
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:163)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:444)
|
||||
... 62 more
|
||||
2023-05-05 12:45:34 database: flush
|
||||
org.h2.message.DbException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]"
|
||||
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]" [50000-210]
|
||||
at org.h2.message.DbException.get(DbException.java:216)
|
||||
at org.h2.message.DbException.convert(DbException.java:414)
|
||||
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:120)
|
||||
at org.h2.mvstore.MVStore.handleException(MVStore.java:3296)
|
||||
at org.h2.mvstore.MVStore.panic(MVStore.java:585)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:461)
|
||||
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4056)
|
||||
at org.h2.mvstore.db.Store.<init>(Store.java:129)
|
||||
at org.h2.engine.Database.<init>(Database.java:324)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
|
||||
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
|
||||
at org.h2.Driver.connect(Driver.java:59)
|
||||
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
|
||||
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
|
||||
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
|
||||
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
|
||||
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.getConnectionUrl(H2ConsoleAutoConfiguration.java:94)
|
||||
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
|
||||
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
|
||||
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
|
||||
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
|
||||
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
|
||||
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
|
||||
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
|
||||
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
|
||||
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
|
||||
at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.logDataSources(H2ConsoleAutoConfiguration.java:86)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.lambda$h2Console$0(H2ConsoleAutoConfiguration.java:69)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.withThreadContextClassLoader(H2ConsoleAutoConfiguration.java:78)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.h2Console(H2ConsoleAutoConfiguration.java:69)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139)
|
||||
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
|
||||
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:645)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1324)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1161)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
|
||||
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:208)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:199)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:94)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:85)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:261)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:235)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:52)
|
||||
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5144)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383)
|
||||
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
|
||||
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
|
||||
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
|
||||
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916)
|
||||
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:886)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383)
|
||||
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
|
||||
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
|
||||
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
|
||||
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916)
|
||||
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:252)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:430)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:926)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:485)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:486)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:210)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:183)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:578)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
|
||||
at com.LabWork.app.AppApplication.main(AppApplication.java:9)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
|
||||
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]"
|
||||
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]" [50000-210]
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:573)
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
|
||||
... 103 more
|
||||
Caused by: org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]
|
||||
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:163)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:444)
|
||||
... 97 more
|
||||
2023-05-05 12:45:35 database: flush
|
||||
org.h2.message.DbException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]"
|
||||
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]" [50000-210]
|
||||
at org.h2.message.DbException.get(DbException.java:216)
|
||||
at org.h2.message.DbException.convert(DbException.java:414)
|
||||
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:120)
|
||||
at org.h2.mvstore.MVStore.handleException(MVStore.java:3296)
|
||||
at org.h2.mvstore.MVStore.panic(MVStore.java:585)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:461)
|
||||
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4056)
|
||||
at org.h2.mvstore.db.Store.<init>(Store.java:129)
|
||||
at org.h2.engine.Database.<init>(Database.java:324)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
|
||||
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
|
||||
at org.h2.Driver.connect(Driver.java:59)
|
||||
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
|
||||
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
|
||||
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
|
||||
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
|
||||
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
|
||||
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:284)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:177)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:36)
|
||||
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:119)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:255)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:230)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:207)
|
||||
at org.hibernate.boot.model.relational.Database.<init>(Database.java:44)
|
||||
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:218)
|
||||
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:191)
|
||||
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:138)
|
||||
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1350)
|
||||
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1421)
|
||||
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
|
||||
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
|
||||
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1130)
|
||||
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:905)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
|
||||
at com.LabWork.app.AppApplication.main(AppApplication.java:9)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
|
||||
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]"
|
||||
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]" [50000-210]
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:573)
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
|
||||
... 64 more
|
||||
Caused by: org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]
|
||||
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:163)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:444)
|
||||
... 58 more
|
||||
2023-05-05 12:45:37 database: flush
|
||||
org.h2.message.DbException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]"
|
||||
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]" [50000-210]
|
||||
at org.h2.message.DbException.get(DbException.java:216)
|
||||
at org.h2.message.DbException.convert(DbException.java:414)
|
||||
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:120)
|
||||
at org.h2.mvstore.MVStore.handleException(MVStore.java:3296)
|
||||
at org.h2.mvstore.MVStore.panic(MVStore.java:585)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:461)
|
||||
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4056)
|
||||
at org.h2.mvstore.db.Store.<init>(Store.java:129)
|
||||
at org.h2.engine.Database.<init>(Database.java:324)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
|
||||
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
|
||||
at org.h2.Driver.connect(Driver.java:59)
|
||||
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
|
||||
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
|
||||
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
|
||||
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
|
||||
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
|
||||
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:284)
|
||||
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:41)
|
||||
at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:63)
|
||||
at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcDatabaseMetaData(ImprovedExtractionContextImpl.java:70)
|
||||
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processTableResultSet(InformationExtractorJdbcDatabaseMetaDataImpl.java:64)
|
||||
at org.hibernate.tool.schema.extract.internal.AbstractInformationExtractorImpl.getTables(AbstractInformationExtractorImpl.java:564)
|
||||
at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.getTablesInformation(DatabaseInformationImpl.java:122)
|
||||
at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:71)
|
||||
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:225)
|
||||
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:126)
|
||||
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:284)
|
||||
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:143)
|
||||
at java.base/java.util.HashMap.forEach(HashMap.java:1421)
|
||||
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:140)
|
||||
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:336)
|
||||
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:415)
|
||||
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1425)
|
||||
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
|
||||
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
|
||||
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1130)
|
||||
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:905)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
|
||||
at com.LabWork.app.AppApplication.main(AppApplication.java:9)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
|
||||
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Внутренняя ошибка: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]"
|
||||
General error: "org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]" [50000-210]
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:573)
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
|
||||
... 68 more
|
||||
Caused by: org.h2.mvstore.MVStoreException: The file is locked: D:/RaspaevNikolayPIbd-21/2_sem/IP/IP_PIbd-21_Raspaev_NI/data.mv.db [2.1.210/7]
|
||||
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:163)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:444)
|
||||
... 62 more
|
||||
|
@ -1,11 +1,15 @@
|
||||
import { useRoutes, Outlet, BrowserRouter } from 'react-router-dom';
|
||||
import { Routes, BrowserRouter, Route } from 'react-router-dom';
|
||||
import Creator from './MainS/Creator';
|
||||
import Reader from './MainS/Reader';
|
||||
import Header from './components/Header';
|
||||
import CreatorAction from './Main/CreatorAction';
|
||||
import ReaderAction from './Main/ReaderAction';
|
||||
import MangaPage from './Main/MangaPage';
|
||||
import UsersPage from './Main/UsersPage';
|
||||
import Catalog from './Main/Catalog';
|
||||
import LoginPage from './Main/LoginPage';
|
||||
import SingupPage from './Main/SingupPage';
|
||||
import PrivateRoutes from "./components/PrivateRoutes";
|
||||
import MangaPage from "./Main/MangaPage";
|
||||
|
||||
function Router(props) {
|
||||
return useRoutes(props.rootRoute);
|
||||
@ -14,30 +18,41 @@ function Router(props) {
|
||||
export default function App() {
|
||||
const routes = [
|
||||
{ index: true, element: <Reader /> },
|
||||
{ path: 'creator', element: <Creator />, label: 'Creator' },
|
||||
{ path: 'reader', element: <Reader />, label: 'Reader' },
|
||||
{ path: 'creatorAction', element: <CreatorAction />, label: 'CreatorAction' },
|
||||
{ path: 'readerAction', element: <ReaderAction />, label: 'ReaderAction' },
|
||||
{ path: 'catalog', element: <Catalog />, label: 'Catalog' },
|
||||
{ path: 'mangapage', element: <MangaPage /> },
|
||||
];
|
||||
const links = routes.filter(route => route.hasOwnProperty('label'));
|
||||
const rootRoute = [
|
||||
{ path: '/', element: render(links), children: routes }
|
||||
];
|
||||
|
||||
function render(links) {
|
||||
return (
|
||||
<>
|
||||
<Header links={links} />
|
||||
<Outlet />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const links = [
|
||||
{ path: 'catalog', label: "Catalog", userGroup: "AUTH" },
|
||||
{ path: 'readerAction', label: "ReaderAction", userGroup: "USER" },
|
||||
{ path: 'creatorAction', label: "CreatorAction", userGroup: "ADMIN" },
|
||||
{ path: 'creator', label: "Creator", userGroup: "ADMIN" },
|
||||
{ path: 'reader', label: "Reader", userGroup: "ADMIN" },
|
||||
{ path: 'users', label: "Users", userGroup: "ADMIN" }
|
||||
];
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Router rootRoute={ rootRoute } />
|
||||
</BrowserRouter>
|
||||
<>
|
||||
<BrowserRouter>
|
||||
<Header links={links}></Header>
|
||||
<div className="content-div">
|
||||
<Routes>
|
||||
<Route element={<LoginPage />} path="/login" />
|
||||
<Route element={<SingupPage />} path="/singup" />
|
||||
<Route element={<PrivateRoutes userGroup="AUTH" />}>
|
||||
<Route element={<MangaPage />} path="/mangapage" />
|
||||
<Route element={<Catalog />} path="/catalog" />
|
||||
<Route element={<Catalog />} path="*" />
|
||||
</Route>
|
||||
<Route element={<PrivateRoutes userGroup="USER" />}>
|
||||
<Route element={<ReaderAction />} path="/readerAction" />
|
||||
</Route>
|
||||
<Route element={<PrivateRoutes userGroup="ADMIN" />}>
|
||||
<Route element={<UsersPage />} path="/users" />
|
||||
<Route element={<Creator />} path="/creator" />
|
||||
<Route element={<Reader />} path="/reader" />
|
||||
<Route element={<CreatorAction />} path="/creatorAction" />
|
||||
</Route>
|
||||
</Routes>
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
8
front/src/Dto/user-singup-dto.js
Normal file
8
front/src/Dto/user-singup-dto.js
Normal file
@ -0,0 +1,8 @@
|
||||
export default class UserSignupDto {
|
||||
constructor(args) {
|
||||
this.login = args.login;
|
||||
this.email = args.email;
|
||||
this.password = args.password;
|
||||
this.passwordConfirm = args.passwordConfirm;
|
||||
}
|
||||
}
|
@ -1,12 +1,9 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import '../components/Banner/banner.css'
|
||||
import Banner from '../components/Banner/Banner.jsx'
|
||||
import { Link, NavLink } from 'react-router-dom';
|
||||
import MangaDto from "../Dto/Manga-Dto";
|
||||
import { NavLink } from 'react-router-dom';
|
||||
|
||||
export default function Catalog() {
|
||||
|
||||
const host = "http://localhost:8080/api";
|
||||
const host = "http://localhost:8080/api/1.0";
|
||||
|
||||
const [mangs, setMangs] = useState([]);
|
||||
|
||||
@ -17,8 +14,18 @@ export default function Catalog() {
|
||||
console.log(mangs);
|
||||
},[]);
|
||||
|
||||
const getTokenForHeader = function () {
|
||||
return "Bearer " + localStorage.getItem("token");
|
||||
}
|
||||
|
||||
const getMangs = async function () {
|
||||
const response = await fetch(host + "/manga");
|
||||
const requestParams = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + "/manga", requestParams);
|
||||
const _data = await response.json()
|
||||
console.log(_data);
|
||||
return _data;
|
||||
@ -26,7 +33,6 @@ export default function Catalog() {
|
||||
|
||||
return (
|
||||
<article className="p-2 catalog_article">
|
||||
<Banner />
|
||||
<div className = "catalog_wrapper">
|
||||
<h1>Каталог</h1>
|
||||
<div className="p-2 d-flex flex-wrap">
|
||||
|
@ -8,7 +8,7 @@ import EditMangaModal from "../components/Modal/EditMangaModal";
|
||||
|
||||
export default function CreatorAction() {
|
||||
|
||||
const host = "http://localhost:8080/api";
|
||||
const host = "http://localhost:8080/api/1.0";
|
||||
|
||||
const [creatorData, setCreatorData] = useState([]);
|
||||
|
||||
@ -24,13 +24,23 @@ export default function CreatorAction() {
|
||||
|
||||
const [mangaModel, setMangaModel] = useState(new MangaDto({}));
|
||||
|
||||
const getTokenForHeader = function () {
|
||||
return "Bearer " + localStorage.getItem("token");
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getCreatorData()
|
||||
.then(_data =>setCreatorData(_data));
|
||||
},[]);
|
||||
|
||||
const getCreatorData = async function () {
|
||||
const response = await fetch(host + "/creator");
|
||||
const requestParams = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + "/creator", requestParams);
|
||||
const _data = await response.json()
|
||||
return _data;
|
||||
}
|
||||
@ -49,6 +59,7 @@ export default function CreatorAction() {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + `/creator/` + id, requestParams);
|
||||
@ -79,6 +90,7 @@ export default function CreatorAction() {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
},
|
||||
body: JSON.stringify(mangaModel),
|
||||
};
|
||||
@ -108,6 +120,7 @@ export default function CreatorAction() {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + `/manga/` + id, requestParams);
|
||||
@ -131,6 +144,7 @@ export default function CreatorAction() {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
},
|
||||
body: JSON.stringify(mangaModel),
|
||||
};
|
||||
|
90
front/src/Main/LoginPage.jsx
Normal file
90
front/src/Main/LoginPage.jsx
Normal file
@ -0,0 +1,90 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { useRef } from "react";
|
||||
|
||||
const hostURL = "http://localhost:8080";
|
||||
|
||||
const LoginPage = function () {
|
||||
|
||||
const loginInput = useRef();
|
||||
const passwordInput = useRef();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
}, []);
|
||||
|
||||
const login = async function (login, password) {
|
||||
const requestParams = {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({login: login, password: password}),
|
||||
};
|
||||
const response = await fetch(hostURL + "/jwt/login", requestParams);
|
||||
const result = await response.text();
|
||||
if (response.status === 200) {
|
||||
localStorage.setItem("token", result);
|
||||
localStorage.setItem("user", login);
|
||||
getRole(result);
|
||||
} else {
|
||||
localStorage.removeItem("token");
|
||||
localStorage.removeItem("user");
|
||||
localStorage.removeItem("role");
|
||||
}
|
||||
}
|
||||
|
||||
const getRole = async function (token) {
|
||||
const requestParams = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
};
|
||||
const requestUrl = hostURL + `/who_am_i?token=${token}`;
|
||||
const response = await fetch(requestUrl, requestParams);
|
||||
const result = await response.text();
|
||||
localStorage.setItem("role", result);
|
||||
window.dispatchEvent(new Event("storage"));
|
||||
navigate("/reader");
|
||||
}
|
||||
|
||||
const loginFormOnSubmit = function (event) {
|
||||
event.preventDefault();
|
||||
login(loginInput.current.value, passwordInput.current.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<form onSubmit={(event) => loginFormOnSubmit(event)}>
|
||||
<div className="mb-3">
|
||||
<p className="mb-1">Login</p>
|
||||
<input className="form-control"
|
||||
type="text" required autoFocus
|
||||
ref={loginInput} />
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<p className="mb-1">Password</p>
|
||||
<input className="form-control"
|
||||
type="password" required
|
||||
ref={passwordInput} />
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<button type="submit" className="btn btn-success">
|
||||
Sing in
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<span>Not a member yet? </span>
|
||||
<Link to="/singup">Sing Up here</Link>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default LoginPage;
|
@ -8,7 +8,11 @@ export default function MangaPage() {
|
||||
|
||||
const [readerData, setReaderData] = useState([]);
|
||||
|
||||
const host = "http://localhost:8080/api";
|
||||
const host = "http://localhost:8080/api/1.0";
|
||||
|
||||
const getTokenForHeader = function () {
|
||||
return "Bearer " + localStorage.getItem("token");
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const quryString = window.location.search;
|
||||
@ -29,6 +33,7 @@ export default function MangaPage() {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + `/manga/` + id + `/readers`, requestParams);
|
||||
@ -52,6 +57,7 @@ export default function MangaPage() {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + `/manga/` + id, requestParams);
|
||||
|
@ -6,7 +6,7 @@ import AddMangaReaderModal from "../components/Modal/AddMangaReaderModal";
|
||||
|
||||
export default function ReaderAction() {
|
||||
|
||||
const host = "http://localhost:8080/api";
|
||||
const host = "http://localhost:8080/api/1.0";
|
||||
|
||||
const [mangaData, setMangaData] = useState([]);
|
||||
|
||||
@ -22,6 +22,10 @@ export default function ReaderAction() {
|
||||
|
||||
const [mangaName, setMangaName] = useState("");
|
||||
|
||||
const getTokenForHeader = function () {
|
||||
return "Bearer " + localStorage.getItem("token");
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const quryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(quryString);
|
||||
@ -37,14 +41,26 @@ export default function ReaderAction() {
|
||||
},[]);
|
||||
|
||||
const getReaderData = async function () {
|
||||
const response = await fetch(host + "/reader");
|
||||
const requestParams = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + "/reader", requestParams);
|
||||
const _data = await response.json()
|
||||
console.log(_data);
|
||||
return _data;
|
||||
}
|
||||
|
||||
const getMangaData = async function () {
|
||||
const response = await fetch(host + "/manga");
|
||||
const requestParams = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + "/manga", requestParams);
|
||||
const _data = await response.json()
|
||||
console.log(_data);
|
||||
return _data;
|
||||
@ -64,6 +80,7 @@ export default function ReaderAction() {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + `/reader/` + id, requestParams);
|
||||
@ -93,6 +110,7 @@ export default function ReaderAction() {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + `/manga/${mangaId}?chapterCount=${chapterCount}`, requestParams);
|
||||
@ -120,6 +138,7 @@ export default function ReaderAction() {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
console.log(host + `/reader/${readerId}/removeManga?mangaId=${id}`, requestParams);
|
||||
@ -143,6 +162,7 @@ export default function ReaderAction() {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
console.log(host + `/reader/${readerId}/addManga?mangaId=${mangaId}`, requestParams);
|
||||
|
88
front/src/Main/SingupPage.jsx
Normal file
88
front/src/Main/SingupPage.jsx
Normal file
@ -0,0 +1,88 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useRef } from "react";
|
||||
|
||||
const hostURL = "http://localhost:8080";
|
||||
|
||||
const SingupPage = function () {
|
||||
|
||||
const loginInput = useRef();
|
||||
const emailInput = useRef();
|
||||
const passwordInput = useRef();
|
||||
const passwordConfirmInput = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
}, []);
|
||||
|
||||
const singup = async function (userSinginDto) {
|
||||
const requestParams = {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(userSinginDto),
|
||||
};
|
||||
console.log(hostURL + "/sing_up");
|
||||
console.log(userSinginDto);
|
||||
const response = await fetch(hostURL + "/sing_up", requestParams);
|
||||
const result = await response.text();
|
||||
alert(result);
|
||||
}
|
||||
|
||||
const singupFormOnSubmit = function (event) {
|
||||
event.preventDefault();
|
||||
const userSinginDto = {
|
||||
login: loginInput.current.value,
|
||||
email: emailInput.current.value,
|
||||
password: passwordInput.current.value,
|
||||
passwordConfirm: passwordConfirmInput.current.value
|
||||
}
|
||||
singup(userSinginDto);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<form onSubmit={(event) => singupFormOnSubmit(event)}>
|
||||
<div className="mb-3">
|
||||
<p className="mb-1">Login</p>
|
||||
<input className="form-control"
|
||||
type="text" required maxLength="64"
|
||||
ref={loginInput} />
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<p className="mb-1">Email</p>
|
||||
<input className="form-control"
|
||||
type="text" required
|
||||
ref={emailInput} />
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<p className="mb-1">Password</p>
|
||||
<input className="form-control"
|
||||
type="password" required minLength="3" maxLength="64"
|
||||
ref={passwordInput} />
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<p className="mb-1">Confirm Password</p>
|
||||
<input className="form-control"
|
||||
type="password" required minLength="3" maxLength="64"
|
||||
ref={passwordConfirmInput} />
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<button type="submit" className="btn btn-success">
|
||||
Create account
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<span>Already have an account? </span>
|
||||
<Link to="/login">Sing In here</Link>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SingupPage;
|
112
front/src/Main/UsersPage.jsx
Normal file
112
front/src/Main/UsersPage.jsx
Normal file
@ -0,0 +1,112 @@
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
const hostURL = "http://localhost:8080";
|
||||
const host = hostURL + "/api/1.0";
|
||||
|
||||
const UsersPage = function () {
|
||||
|
||||
const [users, setUsers] = useState([]);
|
||||
const [pageNumbers, setPageNumbers] = useState([]);
|
||||
const [pageNumber, setPageNumber] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
getUsers(1);
|
||||
}, []);
|
||||
|
||||
const getTokenForHeader = function () {
|
||||
return "Bearer " + localStorage.getItem("token");
|
||||
}
|
||||
|
||||
const getUsers = async function (page) {
|
||||
const requestParams = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const requestUrl = host + `/users?page=${page}`;
|
||||
const response = await fetch(requestUrl, requestParams);
|
||||
const data = await response.json();
|
||||
setUsers(data.first.content);
|
||||
setPageNumber(data.first.number);
|
||||
setPageNumbers(data.second);
|
||||
}
|
||||
|
||||
const removeUser = async function (id) {
|
||||
const requestParams = {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const requestUrl = host + `/user/${id}`;
|
||||
await fetch(requestUrl, requestParams);
|
||||
}
|
||||
|
||||
const pageButtonOnClick = function (page) {
|
||||
getUsers(page);
|
||||
}
|
||||
|
||||
const removeButtonOnClick = function (id) {
|
||||
const confirmResult = confirm("Are you sure you want to remove " +
|
||||
"the selected user?");
|
||||
if (confirmResult === false) {
|
||||
return;
|
||||
}
|
||||
removeUser(id).then(() => getUsers(pageNumber + 1));
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="table-shell mb-3">
|
||||
<table className="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ width: "10%" }} scope="col">#</th>
|
||||
<th style={{ width: "15%" }} scope="col">ID</th>
|
||||
<th style={{ width: "30%" }} scope="col">Login</th>
|
||||
<th style={{ width: "30%" }} scope="col">Email</th>
|
||||
<th style={{ width: "15%" }} scope="col">Role</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.map((user, index) => (
|
||||
<tr>
|
||||
<th style={{ width: "10%" }} scope="row">{index}</th>
|
||||
<td style={{ width: "15%" }}>{user.id}</td>
|
||||
<td style={{ width: "30%" }}>{user.login}</td>
|
||||
<td style={{ width: "30%" }}>{user.email}</td>
|
||||
<td style={{ width: "15%" }}>{user.role}</td>
|
||||
{user.login !== localStorage.getItem("user") ?
|
||||
<td style={{ width: "1%" }}>
|
||||
<button className="btn btn-secondary btn-sm"
|
||||
onClick={() => removeButtonOnClick(user.id)}>
|
||||
del
|
||||
</button>
|
||||
</td> : null}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
Pages:
|
||||
</p>
|
||||
<nav>
|
||||
<ul className="pagination">
|
||||
{pageNumbers.map((number) => (
|
||||
<li className={`page-item ${number === pageNumber + 1 ? "active" : ""}`}
|
||||
onClick={() => pageButtonOnClick(number)}>
|
||||
<a className="page-link" href="#">{number}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default UsersPage;
|
@ -4,7 +4,7 @@ import MangaDto from '../Dto/Manga-Dto';
|
||||
|
||||
export default function Creator() {
|
||||
|
||||
const host = "http://localhost:8080/api";
|
||||
const host = "http://localhost:8080/api/1.0";
|
||||
|
||||
const [creatorId, setCreatorId] = useState(0);
|
||||
|
||||
@ -16,6 +16,9 @@ export default function Creator() {
|
||||
|
||||
const [data, setData] = useState([]);
|
||||
|
||||
const getTokenForHeader = function () {
|
||||
return "Bearer " + localStorage.getItem("token");
|
||||
}
|
||||
|
||||
const table = document.getElementById("tbody");
|
||||
|
||||
@ -24,15 +27,23 @@ export default function Creator() {
|
||||
},[]);
|
||||
|
||||
const getData = async function () {
|
||||
const response = await fetch(host + "/creator");
|
||||
const requestParams = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const requestUrl = host + `/creator`;
|
||||
const response = await fetch(requestUrl, requestParams);
|
||||
setData(await response.json())
|
||||
console.log(data);
|
||||
}
|
||||
}
|
||||
|
||||
const create = async function (){
|
||||
const requestParams = {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
};
|
||||
@ -52,6 +63,7 @@ export default function Creator() {
|
||||
const requestParams = {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
};
|
||||
@ -69,6 +81,9 @@ export default function Creator() {
|
||||
}
|
||||
const requestParams = {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
await fetch(host + `/creator/`, requestParams);
|
||||
}
|
||||
@ -81,6 +96,7 @@ export default function Creator() {
|
||||
const requestParams = {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
};
|
||||
|
@ -3,7 +3,7 @@ import TableReader from '../components/Table/TableReader';
|
||||
|
||||
export default function ReaderS() {
|
||||
|
||||
const host = "http://localhost:8080/api";
|
||||
const host = "http://localhost:8080/api/1.0";
|
||||
|
||||
const [readerId, setReaderId] = useState(0);
|
||||
|
||||
@ -15,8 +15,9 @@ export default function ReaderS() {
|
||||
|
||||
const [data, setData] = useState([]);
|
||||
|
||||
|
||||
|
||||
const getTokenForHeader = function () {
|
||||
return "Bearer " + localStorage.getItem("token");
|
||||
}
|
||||
|
||||
const table = document.getElementById("tbody");
|
||||
|
||||
@ -25,21 +26,30 @@ export default function ReaderS() {
|
||||
console.log(2);
|
||||
},[]);
|
||||
|
||||
|
||||
const getData = async function () {
|
||||
const response = await fetch(host + "/reader");
|
||||
const requestParams = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const requestUrl = host + `/reader`;
|
||||
const response = await fetch(requestUrl, requestParams);
|
||||
setData(await response.json())
|
||||
console.log(data);
|
||||
}
|
||||
}
|
||||
|
||||
const create = async function (){
|
||||
const requestParams = {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + `/reader?readerName=${readerName}&password=${password}`, requestParams);
|
||||
alert(response);
|
||||
console.log(response);
|
||||
getData();
|
||||
}
|
||||
|
||||
@ -55,6 +65,7 @@ export default function ReaderS() {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
const response = await fetch(host + `/reader/` + id, requestParams);
|
||||
@ -70,6 +81,9 @@ export default function ReaderS() {
|
||||
}
|
||||
const requestParams = {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
}
|
||||
};
|
||||
await fetch(host + `/reader/`, requestParams);
|
||||
getData();
|
||||
@ -83,6 +97,7 @@ export default function ReaderS() {
|
||||
const requestParams = {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
};
|
||||
@ -100,6 +115,7 @@ export default function ReaderS() {
|
||||
const requestParams = {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
};
|
||||
@ -112,6 +128,7 @@ export default function ReaderS() {
|
||||
const requestParams = {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Authorization": getTokenForHeader(),
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
};
|
||||
|
@ -1,46 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import React from 'react'
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import banner1 from "../../../img/popular_1.jpg";
|
||||
import banner2 from "../../../img/popular_2.jpg";
|
||||
import banner3 from "../../../img/popular_3.jpg"
|
||||
|
||||
export default function Banner() {
|
||||
const length = 3;
|
||||
var old = length - 1;
|
||||
var current = 0;
|
||||
const navigate = useNavigate();
|
||||
const [bannerState, setBannerState] = useState(["show", "hide", "hide"]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = window.setInterval(() => {
|
||||
setBannerState([
|
||||
...bannerState,
|
||||
(bannerState[current] = "show"),
|
||||
(bannerState[old] = "hide"),
|
||||
]);
|
||||
//setBannerState([...bannerState, ]);
|
||||
|
||||
console.info("Banner changed");
|
||||
|
||||
old = current;
|
||||
current++;
|
||||
|
||||
if (current === length) {
|
||||
current = 0;
|
||||
}
|
||||
}, 2000);
|
||||
|
||||
return () => {
|
||||
window.clearInterval(timer);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="d-flex align-items-center flex-column" id="banner">
|
||||
<a className={bannerState[0]} style={{ cursor: "pointer" }}><img src={banner1}/></a>
|
||||
<a className={bannerState[1]} style={{ cursor: "pointer" }}><img src={banner2}/></a>
|
||||
<a className={bannerState[2]} style={{ cursor: "pointer" }}><img src={banner3}/></a>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
|
||||
|
||||
#banner {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
@keyframes newAnim {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
#banner img {
|
||||
max-width: 90%;
|
||||
border-radius: 5px;
|
||||
animation: newAnim 1s forwards;
|
||||
}
|
||||
|
||||
#banner a.show {
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#banner a.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img.show {
|
||||
max-height: 200px;
|
||||
width: auto;
|
||||
opacity: 1;
|
||||
transition: opacity 1s, visibility 0s;
|
||||
}
|
||||
|
||||
img.hide {
|
||||
max-height: 0;
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 1s, visibility 0s 1s;
|
||||
}
|
||||
|
||||
@media (max-width: 700px){
|
||||
#banner{width: 0px;}
|
||||
#banner_2{width: 0px;}
|
||||
#banner img.show {
|
||||
height: 0;
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 1s, visibility 0s 1s;
|
||||
}
|
||||
#banner h3{
|
||||
font-size: 0em;
|
||||
}
|
||||
#banner_2 h3{
|
||||
font-size: 0em;
|
||||
}
|
||||
#banner_2 img.show {
|
||||
height: 0;
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 1s, visibility 0s 1s;
|
||||
}
|
||||
}
|
@ -1,6 +1,34 @@
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import {NavLink, useNavigate} from 'react-router-dom';
|
||||
import {useEffect, useState} from "react";
|
||||
|
||||
export default function Header(props) {
|
||||
const navigate = useNavigate();
|
||||
const logoutButtonOnClick = function () {
|
||||
localStorage.removeItem("token");
|
||||
localStorage.removeItem("user");
|
||||
localStorage.removeItem("role");
|
||||
window.dispatchEvent(new Event("storage"));
|
||||
navigate("/login");
|
||||
}
|
||||
|
||||
const [userRole, setUserRole] = useState("NONE");
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("storage", () => {
|
||||
getUserRole();
|
||||
});
|
||||
getUserRole();
|
||||
}, [])
|
||||
|
||||
const getUserRole = function () {
|
||||
const role = localStorage.getItem("role") || "NONE";
|
||||
setUserRole(role);
|
||||
}
|
||||
|
||||
const validate = function (userGroup) {
|
||||
return (userGroup === "AUTH" && userRole !== "NONE") || (userGroup === userRole);
|
||||
}
|
||||
console.log(userRole);
|
||||
return (
|
||||
<nav className="navbar navbar-expand-lg navbar-dark">
|
||||
<div className="container-fluid">
|
||||
@ -11,14 +39,27 @@ export default function Header(props) {
|
||||
</button>
|
||||
<div className="collapse navbar-collapse" id="navbarNav">
|
||||
<ul className="navbar-nav">
|
||||
{props.links.map(route =>
|
||||
{props.links.map(route =>{
|
||||
if (validate(route.userGroup)) {
|
||||
return (
|
||||
<li key={route.path}
|
||||
className="nav-item">
|
||||
<NavLink className="nav-link" to={route.path}>
|
||||
{route.label}
|
||||
</NavLink>
|
||||
</li>
|
||||
);}}
|
||||
)}
|
||||
{userRole === "NONE"?
|
||||
null
|
||||
:
|
||||
<div className="border-bottom pb-3 mb-3">
|
||||
<button className="btn btn-primary"
|
||||
onClick={logoutButtonOnClick}>
|
||||
Log Out
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
46
front/src/components/PrivateRoutes.jsx
Normal file
46
front/src/components/PrivateRoutes.jsx
Normal file
@ -0,0 +1,46 @@
|
||||
import {Navigate, Outlet, useNavigate} from 'react-router-dom';
|
||||
import {useEffect} from "react";
|
||||
|
||||
const PrivateRoutes = (props) => {
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("storage", () => {
|
||||
let token = localStorage.getItem("token");
|
||||
if (token) {
|
||||
getRole(token).then((role) => {
|
||||
if (localStorage.getItem("role") != role) {
|
||||
localStorage.removeItem("token");
|
||||
localStorage.removeItem("user");
|
||||
localStorage.removeItem("role");
|
||||
window.dispatchEvent(new Event("storage"));
|
||||
navigate("/catalog");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [])
|
||||
|
||||
const getRole = async function (token) {
|
||||
const requestParams = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
};
|
||||
const requestUrl = `http://localhost:8080/who_am_i?token=${token}`;
|
||||
const response = await fetch(requestUrl, requestParams);
|
||||
return await response.text();
|
||||
}
|
||||
|
||||
let isAllowed = false;
|
||||
let userRole = localStorage.getItem("role");
|
||||
if ((props.userGroup === "AUTH" && userRole) || (props.userGroup === userRole)) {
|
||||
isAllowed = true;
|
||||
}
|
||||
|
||||
return isAllowed ? <Outlet /> : <Navigate to="/login" />;
|
||||
}
|
||||
|
||||
export default PrivateRoutes;
|
@ -2,9 +2,12 @@ package com.LabWork.app.MangaStore.controller;
|
||||
|
||||
|
||||
import com.LabWork.app.MangaStore.configuration.OpenAPI30Configuration;
|
||||
import com.LabWork.app.MangaStore.model.Default.UserRole;
|
||||
import com.LabWork.app.MangaStore.model.Dto.ReaderMangaDto;
|
||||
import com.LabWork.app.MangaStore.model.Dto.SupportDto.MangaDto;
|
||||
import com.LabWork.app.MangaStore.service.ReaderService;
|
||||
import com.LabWork.app.MangaStore.util.validation.ValidationException;
|
||||
import org.springframework.security.access.annotation.Secured;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
@ -31,9 +34,14 @@ public class ReaderController {
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ReaderMangaDto createReader(@RequestParam("readerName") String readerName,
|
||||
@Secured({UserRole.AsString.ADMIN})
|
||||
public String createReader(@RequestParam("readerName") String readerName,
|
||||
@RequestParam("password") String password) {
|
||||
return new ReaderMangaDto(readerService.addReader(readerName, password));
|
||||
try {
|
||||
return new ReaderMangaDto(readerService.addReader(readerName, password)).toString();
|
||||
} catch (ValidationException e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@ -56,6 +64,7 @@ public class ReaderController {
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@Secured({UserRole.AsString.USER})
|
||||
public ReaderMangaDto deleteReader(@PathVariable Long id) {
|
||||
return new ReaderMangaDto(readerService.deleteReader(id));
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ public class UserService implements UserDetailsService {
|
||||
throw new ValidationException("Passwords not equals");
|
||||
}
|
||||
final User user = new User(login, email, passwordEncoder.encode(password), role);
|
||||
validatorUtil.validate(user);
|
||||
//validatorUtil.validate(user);
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
|
@ -9,3 +9,5 @@ spring.jpa.hibernate.ddl-auto=update
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.settings.trace=false
|
||||
spring.h2.console.settings.web-allow-others=false
|
||||
jwt.dev-token=my-secret-jwt
|
||||
jwt.dev=true
|
77
src/test/java/com/LabWork/app/JpaUserTests.java
Normal file
77
src/test/java/com/LabWork/app/JpaUserTests.java
Normal file
@ -0,0 +1,77 @@
|
||||
package com.LabWork.app;
|
||||
|
||||
import com.LabWork.app.MangaStore.model.Default.User;
|
||||
import com.LabWork.app.MangaStore.model.Default.UserRole;
|
||||
import com.LabWork.app.MangaStore.service.Exception.UserNotFoundException;
|
||||
import com.LabWork.app.MangaStore.service.UserService;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SpringBootTest
|
||||
public class JpaUserTests {
|
||||
private static final Logger log = LoggerFactory.getLogger(JpaUserTests.class);
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
|
||||
@Test
|
||||
void testUserCreate() {
|
||||
userService.deleteAllUsers();
|
||||
final User user = userService.addUser("User 1", "email@gmail.com",
|
||||
"123456", "123456", UserRole.USER);
|
||||
log.info("testUserCreate: " + user.toString());
|
||||
Assertions.assertNotNull(user.getId());
|
||||
|
||||
userService.deleteAllUsers();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUserRead() {
|
||||
userService.deleteAllUsers();
|
||||
final User user = userService.addUser("User 2", "email@gmail.com",
|
||||
"123456", "123456", UserRole.USER);
|
||||
log.info("testUserRead[0]: " + user.toString());
|
||||
final User findUser = userService.findUser(user.getId());
|
||||
log.info("testUserRead[1]: " + findUser.toString());
|
||||
Assertions.assertEquals(user, findUser);
|
||||
|
||||
userService.deleteAllUsers();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUserReadNotFound() {
|
||||
userService.deleteAllUsers();
|
||||
Assertions.assertThrows(UserNotFoundException.class, () -> userService.findUser(-1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUserReadAll() {
|
||||
userService.deleteAllUsers();
|
||||
userService.addUser("User 3", "email@gmail.com", "123456",
|
||||
"123456", UserRole.USER);
|
||||
userService.addUser("User 4", "email@gmail.com", "123456",
|
||||
"123456", UserRole.USER);
|
||||
final List<User> users = userService.findAllUsers();
|
||||
log.info("testUserReadAll: " + users.toString());
|
||||
Assertions.assertEquals(users.size(), 2);
|
||||
|
||||
userService.deleteAllUsers();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUserReadAllEmpty() {
|
||||
userService.deleteAllUsers();
|
||||
final List<User> users = userService.findAllUsers();
|
||||
log.info("testUserReadAllEmpty: " + users.toString());
|
||||
Assertions.assertEquals(users.size(), 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user