From c29098d717c82aa97b108034d6728085198ea539 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Fri, 24 Nov 2023 19:26:36 -0800 Subject: [PATCH 001/110] WIP --- wise-webapp/db/wisemapping.properties | 5 + wise-webapp/db/wisemapping.script | 46 +++++ wise-webapp/pom.xml | 174 ++++++------------ .../com/wisemapping/config/Application.java | 16 +- .../wisemapping/config/HibernateConfig.java | 136 +++++++------- .../com/wisemapping/dao/UserManagerImpl.java | 2 +- .../filter/RequestPropertiesInterceptor.java | 4 +- .../wisemapping/service/MailerService.java | 2 +- .../service/google/GoogleService.java | 10 +- .../webmvc/MvcLoginController.java | 2 +- .../application.properties} | 41 ++++- .../resources/spring/wisemapping-common.xml | 7 +- .../resources/spring/wisemapping-rest.xml | 16 +- .../resources/spring/wisemapping-servlet.xml | 22 +-- 14 files changed, 249 insertions(+), 234 deletions(-) create mode 100644 wise-webapp/db/wisemapping.properties create mode 100644 wise-webapp/db/wisemapping.script rename wise-webapp/src/main/{webapp/WEB-INF/app.properties => resources/application.properties} (84%) diff --git a/wise-webapp/db/wisemapping.properties b/wise-webapp/db/wisemapping.properties new file mode 100644 index 00000000..69efbd3e --- /dev/null +++ b/wise-webapp/db/wisemapping.properties @@ -0,0 +1,5 @@ +#HSQL Database Engine 2.7.1 +#Fri Nov 24 19:26:20 PST 2023 +modified=yes +tx_timestamp=458 +version=2.7.1 diff --git a/wise-webapp/db/wisemapping.script b/wise-webapp/db/wisemapping.script new file mode 100644 index 00000000..691beff2 --- /dev/null +++ b/wise-webapp/db/wisemapping.script @@ -0,0 +1,46 @@ +SET DATABASE UNIQUE NAME HSQLDB8C04588647 +SET DATABASE DEFAULT RESULT MEMORY ROWS 0 +SET DATABASE EVENT LOG LEVEL 0 +SET DATABASE TRANSACTION CONTROL LOCKS +SET DATABASE DEFAULT ISOLATION LEVEL READ COMMITTED +SET DATABASE TRANSACTION ROLLBACK ON CONFLICT TRUE +SET DATABASE TEXT TABLE DEFAULTS '' +SET DATABASE SQL NAMES FALSE +SET DATABASE SQL RESTRICT EXEC FALSE +SET DATABASE SQL REFERENCES FALSE +SET DATABASE SQL SIZE TRUE +SET DATABASE SQL TYPES FALSE +SET DATABASE SQL TDC DELETE TRUE +SET DATABASE SQL TDC UPDATE TRUE +SET DATABASE SQL SYS INDEX NAMES TRUE +SET DATABASE SQL CONCAT NULLS TRUE +SET DATABASE SQL UNIQUE NULLS TRUE +SET DATABASE SQL CONVERT TRUNCATE TRUE +SET DATABASE SQL AVG SCALE 0 +SET DATABASE SQL DOUBLE NAN TRUE +SET FILES WRITE DELAY 500 MILLIS +SET FILES BACKUP INCREMENT TRUE +SET FILES CACHE SIZE 10000 +SET FILES CACHE ROWS 50000 +SET FILES SCALE 32 +SET FILES LOB SCALE 32 +SET FILES DEFRAG 0 +SET FILES NIO TRUE +SET FILES NIO SIZE 256 +SET FILES LOG TRUE +SET FILES LOG SIZE 50 +SET FILES CHECK 458 +SET DATABASE COLLATION "SQL_TEXT" PAD SPACE +CREATE USER SA PASSWORD DIGEST 'd41d8cd98f00b204e9800998ecf8427e' +ALTER USER SA SET LOCAL TRUE +CREATE SCHEMA PUBLIC AUTHORIZATION DBA +ALTER SEQUENCE SYSTEM_LOBS.LOB_ID RESTART WITH 1 +SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CARDINAL_NUMBER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.YES_OR_NO TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CHARACTER_DATA TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.SQL_IDENTIFIER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.TIME_STAMP TO PUBLIC +GRANT DBA TO SA +SET SCHEMA SYSTEM_LOBS +INSERT INTO BLOCKS VALUES(0,2147483647,0) diff --git a/wise-webapp/pom.xml b/wise-webapp/pom.xml index 9a5d45b0..3e42f21d 100644 --- a/wise-webapp/pom.xml +++ b/wise-webapp/pom.xml @@ -2,19 +2,22 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 wise-webapp - war WiseMapping Webapp http://www.wisemapping.org + 5.1.0-SNAPSHOT + - org.wisemapping - wisemapping - ../pom.xml - 5.1.0-SNAPSHOT + org.springframework.boot + spring-boot-starter-parent + 3.1.2 - 6.0.14 - 6.1.5 + 5.1.0-SNAPSHOT + 17 + 17 + 6.0.11 + 6.1.2 6.0.2 @@ -31,6 +34,27 @@ 1.7 compile + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-mail + + org.testng testng @@ -43,55 +67,42 @@ 12.0 compile - - org.springframework - spring-webmvc - ${org.springframework.version} - compile - - - org.springframework - spring-messaging - ${org.springframework.version} - - - org.springframework - spring-websocket - ${org.springframework.version} - + + + + + + + + + + org.postgresql postgresql 42.5.4 - - org.springframework - spring-beans - ${org.springframework.version} - compile - - - org.springframework - spring-tx - ${org.springframework.version} - compile - + + + + + + + + + + + + org.springframework.security spring-security-taglibs ${spring-security-taglibs.version} - - - org.hibernate - hibernate-core - 6.1.7.Final - - jakarta.xml.bind jakarta.xml.bind-api - 4.0.1 + 4.0.0 @@ -100,78 +111,6 @@ hibernate-validator 8.0.1.Final - - - org.springframework - spring-orm - ${org.springframework.version} - compile - - - org.springframework - spring-context - ${org.springframework.version} - compile - - - org.springframework - spring-web - ${org.springframework.version} - compile - - - org.springframework - spring-oxm - ${org.springframework.version} - compile - - - org.springframework - spring-context-support - ${org.springframework.version} - compile - - - org.springframework.data - spring-data-jpa - 3.1.0 - - - org.springframework - spring-test - 6.0.6 - test - - - - org.springframework - spring-aop - ${org.springframework.version} - - - org.springframework.security - spring-security-web - ${org.springframework.addons} - compile - - - org.springframework.security - spring-security-core - ${org.springframework.addons} - compile - - - org.springframework - spring-jdbc - ${org.springframework.version} - runtime - - - aopalliance - aopalliance - 1.0 - compile - jakarta.mail jakarta.mail-api @@ -280,10 +219,9 @@ org.hsqldb hsqldb - 2.7.1 + 2.7.2 - drop-schemas @@ -395,6 +333,8 @@ + + org.apache.maven.plugins maven-surefire-plugin diff --git a/wise-webapp/src/main/java/com/wisemapping/config/Application.java b/wise-webapp/src/main/java/com/wisemapping/config/Application.java index 54b02bda..76759277 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/Application.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/Application.java @@ -1,11 +1,12 @@ package com.wisemapping.config; -import org.springframework.beans.factory.annotation.Autowired; +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.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; -import org.springframework.transaction.TransactionManager; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ViewResolver; @@ -18,11 +19,18 @@ import org.springframework.web.servlet.view.JstlView; @Configuration @EnableTransactionManagement @ComponentScan +@SpringBootApplication +@EnableJpaRepositories("com.wisemapping.model") @ImportResource("classpath:spring/wisemapping-common.xml") public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + @Bean HandlerExceptionResolver errorHandler() { - final SimpleMappingExceptionResolver result = new SimpleMappingExceptionResolver(); + final SimpleMappingExceptionResolver result = new SimpleMappingExceptionResolver(); //mapping status code with view response. result.addStatusCode("reactInclude", 403); @@ -34,7 +42,7 @@ public class Application { } @Bean - public ViewResolver viewResolver(){ + public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); diff --git a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java index 401f7f0a..1caa213b 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java @@ -1,8 +1,6 @@ package com.wisemapping.config; import org.apache.commons.dbcp2.BasicDataSource; -import org.hibernate.SessionFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -17,72 +15,72 @@ import java.util.Properties; @EnableTransactionManagement public class HibernateConfig { - @Value("${database.hibernate.dialect}") - private String dbDialect; +// @Value("${database.hibernate.dialect}") +// private String dbDialect; +// +// @Value("${database.driver}") +// private String dbDriver; +// +// @Value("${database.url}") +// private String dbUrl; +// +// @Value("${database.username}") +// private String dbUsername; +// @Value("${database.password}") +// private String dbPassword; +// +// @Value("${database.validation.enabled:true}") +// private boolean dbSetOnBorrow; +// +// @Value("${database.validation.query:SELECT 1}") +// private String dbValQuery; - @Value("${database.driver}") - private String dbDriver; - - @Value("${database.url}") - private String dbUrl; - - @Value("${database.username}") - private String dbUsername; - @Value("${database.password}") - private String dbPassword; - - @Value("${database.validation.enabled:true}") - private boolean dbSetOnBorrow; - - @Value("${database.validation.query:SELECT 1}") - private String dbValQuery; - - @Bean - public LocalSessionFactoryBean sessionFactory() { - final LocalSessionFactoryBean result = new LocalSessionFactoryBean(); - result.setPackagesToScan("com.wisemapping.model"); - result.setDataSource(dataSource()); - result.setHibernateProperties(hibernateProperties()); - - return result; - } - - - @Bean - public HibernateTransactionManager hibernateTransactionManager() { - final HibernateTransactionManager result = new HibernateTransactionManager(); - result.setNestedTransactionAllowed(true); - // @Todo: Am I creatting two instances ??? - result.setSessionFactory(sessionFactory().getObject()); - return result; - } - - private Properties hibernateProperties() { - final Properties result = new Properties(); - result.setProperty("hibernate.dialect", dbDialect); - result.setProperty("hibernate.default_batch_fetch_size", "200"); - result.setProperty("hibernate.nestedTransactionAllowed", "true"); - result.setProperty("hibernate.auto_quote_keyword", "true"); - - return result; - } - - @Bean - public DataSource dataSource() { - final BasicDataSource result = new BasicDataSource(); - result.setDriverClassName(dbDriver); - result.setUrl(dbUrl); - result.setUsername(dbUsername); - result.setPassword(dbPassword); - result.setTestOnBorrow(dbSetOnBorrow); - - result.setDefaultQueryTimeout(15); - result.setMaxTotal(100); - result.setMaxIdle(30); - result.setInitialSize(5); - result.setMaxWaitMillis(10000); - result.setValidationQuery(dbValQuery); - - return result; - } +// @Bean +// public LocalSessionFactoryBean sessionFactory() { +// final LocalSessionFactoryBean result = new LocalSessionFactoryBean(); +// result.setPackagesToScan("com.wisemapping.model"); +// result.setDataSource(dataSource()); +// result.setHibernateProperties(hibernateProperties()); +// +// return result; +// } +// +// +// @Bean +// public HibernateTransactionManager hibernateTransactionManager() { +// final HibernateTransactionManager result = new HibernateTransactionManager(); +// result.setNestedTransactionAllowed(true); +// // @Todo: Am I creatting two instances ??? +// result.setSessionFactory(sessionFactory().getObject()); +// return result; +// } +// +// private Properties hibernateProperties() { +// final Properties result = new Properties(); +// result.setProperty("hibernate.dialect", dbDialect); +// result.setProperty("hibernate.default_batch_fetch_size", "200"); +// result.setProperty("hibernate.nestedTransactionAllowed", "true"); +// result.setProperty("hibernate.auto_quote_keyword", "true"); +// +// return result; +// } +// +// @Bean +// public DataSource dataSource() { +// final BasicDataSource result = new BasicDataSource(); +// result.setDriverClassName(dbDriver); +// result.setUrl(dbUrl); +// result.setUsername(dbUsername); +// result.setPassword(dbPassword); +// result.setTestOnBorrow(dbSetOnBorrow); +// +// result.setDefaultQueryTimeout(15); +// result.setMaxTotal(100); +// result.setMaxIdle(30); +// result.setInitialSize(5); +// result.setMaxWaitMillis(10000); +// result.setValidationQuery(dbValQuery); +// +// return result; +// } } diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java b/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java index d47bc41b..78c013b6 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java +++ b/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java @@ -39,7 +39,7 @@ import java.util.concurrent.CopyOnWriteArraySet; @Repository public class UserManagerImpl implements UserManager { - @Autowired +// @Autowired private SessionFactory sessionFactory; @Autowired diff --git a/wise-webapp/src/main/java/com/wisemapping/filter/RequestPropertiesInterceptor.java b/wise-webapp/src/main/java/com/wisemapping/filter/RequestPropertiesInterceptor.java index ddc03d1b..00c5d1cb 100644 --- a/wise-webapp/src/main/java/com/wisemapping/filter/RequestPropertiesInterceptor.java +++ b/wise-webapp/src/main/java/com/wisemapping/filter/RequestPropertiesInterceptor.java @@ -48,7 +48,7 @@ public class RequestPropertiesInterceptor implements HandlerInterceptor { @Value("${site.homepage}") private String siteHomepage; - @Value("${site.baseurl}") + @Value("${site.baseurl:}") private String siteUrl; @Value("${security.type}") @@ -75,7 +75,7 @@ public class RequestPropertiesInterceptor implements HandlerInterceptor { request.setAttribute("security.type", securityType); // If the property could not be resolved, try to infer one from the request... - if ("${site.baseurl}".equals(siteUrl)) { + if (siteUrl.isBlank()) { siteUrl = request.getRequestURL().toString().replace(request.getRequestURI(), request.getContextPath()); } request.setAttribute("site.baseurl", siteUrl); diff --git a/wise-webapp/src/main/java/com/wisemapping/service/MailerService.java b/wise-webapp/src/main/java/com/wisemapping/service/MailerService.java index fabd6385..93c512d2 100644 --- a/wise-webapp/src/main/java/com/wisemapping/service/MailerService.java +++ b/wise-webapp/src/main/java/com/wisemapping/service/MailerService.java @@ -50,7 +50,7 @@ public final class MailerService { @Value("${mail.supportEmail}") private String supportEmail; - @Value("${mail.errorReporterEmail}") + @Value("${mail.errorReporterEmail:}") private String errorReporterEmail; //~ Methods .............................................................................................. diff --git a/wise-webapp/src/main/java/com/wisemapping/service/google/GoogleService.java b/wise-webapp/src/main/java/com/wisemapping/service/google/GoogleService.java index 0978a311..8bbb6267 100644 --- a/wise-webapp/src/main/java/com/wisemapping/service/google/GoogleService.java +++ b/wise-webapp/src/main/java/com/wisemapping/service/google/GoogleService.java @@ -34,15 +34,15 @@ import com.wisemapping.service.google.http.HttpInvokerException; public class GoogleService { @Autowired private HttpInvoker httpInvoker; - @Value("${security.oauth2.google.confirmUrl}") + @Value("${security.oauth2.google.confirmUrl:}") private String optinConfirmUrl; - @Value("${security.oauth2.google.userinfoUrl}") + @Value("${security.oauth2.google.userinfoUrl:}") private String accountBasicDataUrl; - @Value("${security.oauth2.google.clientId}") + @Value("${security.oauth2.google.clientId:}") private String clientId; - @Value("${security.oauth2.google.clientSecret}") + @Value("${security.oauth2.google.clientSecret:}") private String clientSecret; - @Value("${security.oauth2.google.callbackUrl}") + @Value("${security.oauth2.google.callbackUrl:}") private String callbackUrl; public void setHttpInvoker(HttpInvoker httpInvoker) { diff --git a/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcLoginController.java b/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcLoginController.java index 2e972b5e..b21c279c 100644 --- a/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcLoginController.java +++ b/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcLoginController.java @@ -31,7 +31,7 @@ import org.springframework.web.servlet.ModelAndView; @PreAuthorize("permitAll()") public class MvcLoginController { - @Value("${database.driver}") +// @Value("${database.driver}") private String driver; @RequestMapping(value = "login", method = RequestMethod.GET) diff --git a/wise-webapp/src/main/webapp/WEB-INF/app.properties b/wise-webapp/src/main/resources/application.properties similarity index 84% rename from wise-webapp/src/main/webapp/WEB-INF/app.properties rename to wise-webapp/src/main/resources/application.properties index 0046539e..c787ae43 100755 --- a/wise-webapp/src/main/webapp/WEB-INF/app.properties +++ b/wise-webapp/src/main/resources/application.properties @@ -22,15 +22,16 @@ #database.validation.enabled=false -# HSQL Configuration properties -database.url=jdbc:hsqldb:file:${database.base.url}/db/wisemapping -database.driver=org.hsqldb.jdbc.JDBCDriver -database.hibernate.dialect=org.hibernate.dialect.HSQLDialect - -database.username=sa -database.password= -database.validation.enabled=false -database.validation.query= +##database.base.url=/Users/veigap/repos/wisemapping-open-source/wise-webapp +### HSQL Configuration properties +##database.url=jdbc:hsqldb:file:${database.base.url}/db/wisemapping +##database.driver=org.hsqldb.jdbc.JDBCDriver +##database.hibernate.dialect=org.hibernate.dialect.HSQLDialect +# +#database.username=sa +#database.password= +#database.validation.enabled=false +#database.validation.query= ################################################################################## # Mail configuration. Must be configured to enable user registration confirmation. @@ -149,7 +150,9 @@ security.oauth2.google.confirmUrl=https://oauth2.googleapis.com/token # Google service for get user data (name, email, etc) security.oauth2.google.userinfoUrl=https://www.googleapis.com/oauth2/v3/userinfo # Url for starting auth process with google -security.oauth2.google.url=https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=${security.oauth2.google.callbackUrl}&prompt=consent&response_type=code&client_id=${security.oauth2.google.clientId}&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&access_type=offline&state=wisemapping&include_granted_scopes=true + +@Todo +security.oauth2.google.url=https//review @@ -161,3 +164,21 @@ security.oauth2.google.url=https://accounts.google.com/o/oauth2/v2/auth?redirect # Coma separated list of domains and emails ban #accounts.exclusion.domain= + +####################################################################################### +# Spring related configurations +####################################################################################### +spring.main.allow-circular-references=true + +database.base.url=/Users/veigap/repos/wisemapping-open-source/wise-webapp +spring.datasource.url=jdbc:hsqldb:file:${database.base.url}/db/wisemapping +spring.datasource.username=sa +spring.datasource.password= +spring.datasource.driver-class-name = org.hsqldb.jdbc.JDBCDriver +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect +spring.jpa.open-in-view=true +spring.h2.console.enabled=true +spring.h2.console.path=/h2-ui + + + diff --git a/wise-webapp/src/main/resources/spring/wisemapping-common.xml b/wise-webapp/src/main/resources/spring/wisemapping-common.xml index ef3b1361..c7c41d44 100644 --- a/wise-webapp/src/main/resources/spring/wisemapping-common.xml +++ b/wise-webapp/src/main/resources/spring/wisemapping-common.xml @@ -1,13 +1,10 @@ + http://www.springframework.org/schema/beans/spring-beans.xsd"> - + diff --git a/wise-webapp/src/main/resources/spring/wisemapping-rest.xml b/wise-webapp/src/main/resources/spring/wisemapping-rest.xml index 5c2da2db..fa3b1967 100644 --- a/wise-webapp/src/main/resources/spring/wisemapping-rest.xml +++ b/wise-webapp/src/main/resources/spring/wisemapping-rest.xml @@ -50,12 +50,12 @@ - - - - - messages - - - + + + + + + + + \ No newline at end of file diff --git a/wise-webapp/src/main/resources/spring/wisemapping-servlet.xml b/wise-webapp/src/main/resources/spring/wisemapping-servlet.xml index e194f74b..1c93d70d 100644 --- a/wise-webapp/src/main/resources/spring/wisemapping-servlet.xml +++ b/wise-webapp/src/main/resources/spring/wisemapping-servlet.xml @@ -19,16 +19,16 @@ - - + + + - - - - - messages - - - + + + + + + + + From 52d684d61118726772445319ab94a42c4b95f22b Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 26 Nov 2023 15:42:22 -0800 Subject: [PATCH 002/110] Fix JPA. --- wise-webapp/db/wisemapping.properties | 5 -- wise-webapp/db/wisemapping.script | 46 ------------------- .../com/wisemapping/config/Application.java | 2 - .../wisemapping/config/HibernateConfig.java | 4 +- .../com/wisemapping/dao/MindmapManager.java | 1 - .../wisemapping/dao/MindmapManagerImpl.java | 8 +++- .../src/main/resources/application.properties | 1 + 7 files changed, 11 insertions(+), 56 deletions(-) delete mode 100644 wise-webapp/db/wisemapping.properties delete mode 100644 wise-webapp/db/wisemapping.script diff --git a/wise-webapp/db/wisemapping.properties b/wise-webapp/db/wisemapping.properties deleted file mode 100644 index 69efbd3e..00000000 --- a/wise-webapp/db/wisemapping.properties +++ /dev/null @@ -1,5 +0,0 @@ -#HSQL Database Engine 2.7.1 -#Fri Nov 24 19:26:20 PST 2023 -modified=yes -tx_timestamp=458 -version=2.7.1 diff --git a/wise-webapp/db/wisemapping.script b/wise-webapp/db/wisemapping.script deleted file mode 100644 index 691beff2..00000000 --- a/wise-webapp/db/wisemapping.script +++ /dev/null @@ -1,46 +0,0 @@ -SET DATABASE UNIQUE NAME HSQLDB8C04588647 -SET DATABASE DEFAULT RESULT MEMORY ROWS 0 -SET DATABASE EVENT LOG LEVEL 0 -SET DATABASE TRANSACTION CONTROL LOCKS -SET DATABASE DEFAULT ISOLATION LEVEL READ COMMITTED -SET DATABASE TRANSACTION ROLLBACK ON CONFLICT TRUE -SET DATABASE TEXT TABLE DEFAULTS '' -SET DATABASE SQL NAMES FALSE -SET DATABASE SQL RESTRICT EXEC FALSE -SET DATABASE SQL REFERENCES FALSE -SET DATABASE SQL SIZE TRUE -SET DATABASE SQL TYPES FALSE -SET DATABASE SQL TDC DELETE TRUE -SET DATABASE SQL TDC UPDATE TRUE -SET DATABASE SQL SYS INDEX NAMES TRUE -SET DATABASE SQL CONCAT NULLS TRUE -SET DATABASE SQL UNIQUE NULLS TRUE -SET DATABASE SQL CONVERT TRUNCATE TRUE -SET DATABASE SQL AVG SCALE 0 -SET DATABASE SQL DOUBLE NAN TRUE -SET FILES WRITE DELAY 500 MILLIS -SET FILES BACKUP INCREMENT TRUE -SET FILES CACHE SIZE 10000 -SET FILES CACHE ROWS 50000 -SET FILES SCALE 32 -SET FILES LOB SCALE 32 -SET FILES DEFRAG 0 -SET FILES NIO TRUE -SET FILES NIO SIZE 256 -SET FILES LOG TRUE -SET FILES LOG SIZE 50 -SET FILES CHECK 458 -SET DATABASE COLLATION "SQL_TEXT" PAD SPACE -CREATE USER SA PASSWORD DIGEST 'd41d8cd98f00b204e9800998ecf8427e' -ALTER USER SA SET LOCAL TRUE -CREATE SCHEMA PUBLIC AUTHORIZATION DBA -ALTER SEQUENCE SYSTEM_LOBS.LOB_ID RESTART WITH 1 -SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CARDINAL_NUMBER TO PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.YES_OR_NO TO PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CHARACTER_DATA TO PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.SQL_IDENTIFIER TO PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.TIME_STAMP TO PUBLIC -GRANT DBA TO SA -SET SCHEMA SYSTEM_LOBS -INSERT INTO BLOCKS VALUES(0,2147483647,0) diff --git a/wise-webapp/src/main/java/com/wisemapping/config/Application.java b/wise-webapp/src/main/java/com/wisemapping/config/Application.java index 76759277..c694c89a 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/Application.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/Application.java @@ -16,9 +16,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @EnableWebMvc -@Configuration @EnableTransactionManagement -@ComponentScan @SpringBootApplication @EnableJpaRepositories("com.wisemapping.model") @ImportResource("classpath:spring/wisemapping-common.xml") diff --git a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java index 1caa213b..a4e19549 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java @@ -1,6 +1,9 @@ package com.wisemapping.config; +import jakarta.persistence.EntityManagerFactory; import org.apache.commons.dbcp2.BasicDataSource; +import org.hibernate.SessionFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -14,7 +17,6 @@ import java.util.Properties; @Configuration @EnableTransactionManagement public class HibernateConfig { - // @Value("${database.hibernate.dialect}") // private String dbDialect; // diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManager.java b/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManager.java index 3bff94cc..f2a34259 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManager.java +++ b/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManager.java @@ -22,7 +22,6 @@ import com.wisemapping.model.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; import java.util.List; public interface MindmapManager { diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java b/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java index 4892391c..adc8f841 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java +++ b/wise-webapp/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java @@ -20,6 +20,7 @@ package com.wisemapping.dao; import com.wisemapping.model.*; import jakarta.annotation.Resource; +import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaQuery; @@ -29,6 +30,7 @@ import org.hibernate.SessionFactory; import org.hibernate.query.SelectionQuery; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.Calendar; @@ -37,7 +39,11 @@ import java.util.List; @Repository("mindmapManager") public class MindmapManagerImpl implements MindmapManager { - @Resource + + @Autowired + private EntityManagerFactory entityManagerFactory; + + @Autowired private SessionFactory sessionFactory; @Override diff --git a/wise-webapp/src/main/resources/application.properties b/wise-webapp/src/main/resources/application.properties index c787ae43..04a919e7 100755 --- a/wise-webapp/src/main/resources/application.properties +++ b/wise-webapp/src/main/resources/application.properties @@ -180,5 +180,6 @@ spring.jpa.open-in-view=true spring.h2.console.enabled=true spring.h2.console.path=/h2-ui +spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext From ea6b2ad1063e52f7d87c5cbfcd36efd186d9352f Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 26 Nov 2023 16:13:45 -0800 Subject: [PATCH 003/110] Fix public resource sharing. --- .../com/wisemapping/config/Application.java | 32 ------------- .../wisemapping/config/HibernateConfig.java | 11 ----- .../com/wisemapping/config/MvcConfig.java | 45 ++++++++++++++++++ .../src/main/resources/application.properties | 4 -- .../main/{webapp => resources/public}/ads.txt | 0 .../public}/css/viewonly.css | 0 .../{webapp => resources/public}/favicon.ico | Bin .../{webapp => resources/public}/favicon.png | Bin .../public}/images/add.svg | 0 .../public}/images/center_focus.svg | 0 .../public}/images/logo-icon.png | Bin .../public}/images/logo-icon.svg | 0 .../public}/images/logo-small.png | Bin .../public}/images/logo-text-black.svg | 0 .../public}/images/minus.svg | 0 .../{webapp => resources/public}/index.html | 0 .../{webapp => resources/public}/robots.txt | 0 .../WEB-INF => resources}/views/init.jsp | 0 .../views/mindmapEditor.jsp | 0 .../views/mindmapViewonly.jsp | 0 .../views/pageHeaders.jsf | 0 .../views/reactInclude.jsp | 0 .../src/main/webapp/META-INF/Context.xml | 16 ------- wise-webapp/src/main/webapp/index.jsp | 3 -- 24 files changed, 45 insertions(+), 66 deletions(-) create mode 100644 wise-webapp/src/main/java/com/wisemapping/config/MvcConfig.java rename wise-webapp/src/main/{webapp => resources/public}/ads.txt (100%) rename wise-webapp/src/main/{webapp => resources/public}/css/viewonly.css (100%) rename wise-webapp/src/main/{webapp => resources/public}/favicon.ico (100%) rename wise-webapp/src/main/{webapp => resources/public}/favicon.png (100%) rename wise-webapp/src/main/{webapp => resources/public}/images/add.svg (100%) rename wise-webapp/src/main/{webapp => resources/public}/images/center_focus.svg (100%) rename wise-webapp/src/main/{webapp => resources/public}/images/logo-icon.png (100%) rename wise-webapp/src/main/{webapp => resources/public}/images/logo-icon.svg (100%) rename wise-webapp/src/main/{webapp => resources/public}/images/logo-small.png (100%) rename wise-webapp/src/main/{webapp => resources/public}/images/logo-text-black.svg (100%) rename wise-webapp/src/main/{webapp => resources/public}/images/minus.svg (100%) rename wise-webapp/src/main/{webapp => resources/public}/index.html (100%) rename wise-webapp/src/main/{webapp => resources/public}/robots.txt (100%) rename wise-webapp/src/main/{webapp/WEB-INF => resources}/views/init.jsp (100%) rename wise-webapp/src/main/{webapp/WEB-INF => resources}/views/mindmapEditor.jsp (100%) rename wise-webapp/src/main/{webapp/WEB-INF => resources}/views/mindmapViewonly.jsp (100%) rename wise-webapp/src/main/{webapp/WEB-INF => resources}/views/pageHeaders.jsf (100%) rename wise-webapp/src/main/{webapp/WEB-INF => resources}/views/reactInclude.jsp (100%) delete mode 100755 wise-webapp/src/main/webapp/META-INF/Context.xml delete mode 100644 wise-webapp/src/main/webapp/index.jsp diff --git a/wise-webapp/src/main/java/com/wisemapping/config/Application.java b/wise-webapp/src/main/java/com/wisemapping/config/Application.java index c694c89a..e22ae7ed 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/Application.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/Application.java @@ -2,20 +2,10 @@ package com.wisemapping.config; 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.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.springframework.web.servlet.HandlerExceptionResolver; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; -@EnableWebMvc @EnableTransactionManagement @SpringBootApplication @EnableJpaRepositories("com.wisemapping.model") @@ -25,26 +15,4 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } - - @Bean - HandlerExceptionResolver errorHandler() { - final SimpleMappingExceptionResolver result = new SimpleMappingExceptionResolver(); - - //mapping status code with view response. - result.addStatusCode("reactInclude", 403); - - //setting default error view - result.setDefaultErrorView("reactInclude"); - result.setDefaultStatusCode(500); - return result; - } - - @Bean - public ViewResolver viewResolver() { - InternalResourceViewResolver resolver = new InternalResourceViewResolver(); - resolver.setPrefix("/WEB-INF/views/"); - resolver.setSuffix(".jsp"); - resolver.setViewClass(JstlView.class); - return resolver; - } } diff --git a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java index a4e19549..8e25e9ce 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java @@ -1,19 +1,8 @@ package com.wisemapping.config; -import jakarta.persistence.EntityManagerFactory; -import org.apache.commons.dbcp2.BasicDataSource; -import org.hibernate.SessionFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.orm.hibernate5.HibernateTransactionManager; -import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; -import javax.sql.DataSource; -import java.util.Properties; - @Configuration @EnableTransactionManagement public class HibernateConfig { diff --git a/wise-webapp/src/main/java/com/wisemapping/config/MvcConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/MvcConfig.java new file mode 100644 index 00000000..7c86002c --- /dev/null +++ b/wise-webapp/src/main/java/com/wisemapping/config/MvcConfig.java @@ -0,0 +1,45 @@ +package com.wisemapping.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.servlet.view.JstlView; + +@Configuration +@EnableWebMvc +public class MvcConfig implements WebMvcConfigurer { + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry + .addResourceHandler("/**") + .addResourceLocations("classpath:/public/"); + } + + @Bean + public ViewResolver viewResolver() { + InternalResourceViewResolver resolver = new InternalResourceViewResolver(); + resolver.setPrefix("/views/"); + resolver.setSuffix(".jsp"); + resolver.setViewClass(JstlView.class); + return resolver; + } + + @Bean + HandlerExceptionResolver errorHandler() { + final SimpleMappingExceptionResolver result = new SimpleMappingExceptionResolver(); + + //mapping status code with view response. + result.addStatusCode("reactInclude", 403); + + //setting default error view + result.setDefaultErrorView("reactInclude"); + result.setDefaultStatusCode(500); + return result; + } +} \ No newline at end of file diff --git a/wise-webapp/src/main/resources/application.properties b/wise-webapp/src/main/resources/application.properties index 04a919e7..fbd8c1f9 100755 --- a/wise-webapp/src/main/resources/application.properties +++ b/wise-webapp/src/main/resources/application.properties @@ -179,7 +179,3 @@ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect spring.jpa.open-in-view=true spring.h2.console.enabled=true spring.h2.console.path=/h2-ui - -spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext - - diff --git a/wise-webapp/src/main/webapp/ads.txt b/wise-webapp/src/main/resources/public/ads.txt similarity index 100% rename from wise-webapp/src/main/webapp/ads.txt rename to wise-webapp/src/main/resources/public/ads.txt diff --git a/wise-webapp/src/main/webapp/css/viewonly.css b/wise-webapp/src/main/resources/public/css/viewonly.css similarity index 100% rename from wise-webapp/src/main/webapp/css/viewonly.css rename to wise-webapp/src/main/resources/public/css/viewonly.css diff --git a/wise-webapp/src/main/webapp/favicon.ico b/wise-webapp/src/main/resources/public/favicon.ico similarity index 100% rename from wise-webapp/src/main/webapp/favicon.ico rename to wise-webapp/src/main/resources/public/favicon.ico diff --git a/wise-webapp/src/main/webapp/favicon.png b/wise-webapp/src/main/resources/public/favicon.png similarity index 100% rename from wise-webapp/src/main/webapp/favicon.png rename to wise-webapp/src/main/resources/public/favicon.png diff --git a/wise-webapp/src/main/webapp/images/add.svg b/wise-webapp/src/main/resources/public/images/add.svg similarity index 100% rename from wise-webapp/src/main/webapp/images/add.svg rename to wise-webapp/src/main/resources/public/images/add.svg diff --git a/wise-webapp/src/main/webapp/images/center_focus.svg b/wise-webapp/src/main/resources/public/images/center_focus.svg similarity index 100% rename from wise-webapp/src/main/webapp/images/center_focus.svg rename to wise-webapp/src/main/resources/public/images/center_focus.svg diff --git a/wise-webapp/src/main/webapp/images/logo-icon.png b/wise-webapp/src/main/resources/public/images/logo-icon.png similarity index 100% rename from wise-webapp/src/main/webapp/images/logo-icon.png rename to wise-webapp/src/main/resources/public/images/logo-icon.png diff --git a/wise-webapp/src/main/webapp/images/logo-icon.svg b/wise-webapp/src/main/resources/public/images/logo-icon.svg similarity index 100% rename from wise-webapp/src/main/webapp/images/logo-icon.svg rename to wise-webapp/src/main/resources/public/images/logo-icon.svg diff --git a/wise-webapp/src/main/webapp/images/logo-small.png b/wise-webapp/src/main/resources/public/images/logo-small.png similarity index 100% rename from wise-webapp/src/main/webapp/images/logo-small.png rename to wise-webapp/src/main/resources/public/images/logo-small.png diff --git a/wise-webapp/src/main/webapp/images/logo-text-black.svg b/wise-webapp/src/main/resources/public/images/logo-text-black.svg similarity index 100% rename from wise-webapp/src/main/webapp/images/logo-text-black.svg rename to wise-webapp/src/main/resources/public/images/logo-text-black.svg diff --git a/wise-webapp/src/main/webapp/images/minus.svg b/wise-webapp/src/main/resources/public/images/minus.svg similarity index 100% rename from wise-webapp/src/main/webapp/images/minus.svg rename to wise-webapp/src/main/resources/public/images/minus.svg diff --git a/wise-webapp/src/main/webapp/index.html b/wise-webapp/src/main/resources/public/index.html similarity index 100% rename from wise-webapp/src/main/webapp/index.html rename to wise-webapp/src/main/resources/public/index.html diff --git a/wise-webapp/src/main/webapp/robots.txt b/wise-webapp/src/main/resources/public/robots.txt similarity index 100% rename from wise-webapp/src/main/webapp/robots.txt rename to wise-webapp/src/main/resources/public/robots.txt diff --git a/wise-webapp/src/main/webapp/WEB-INF/views/init.jsp b/wise-webapp/src/main/resources/views/init.jsp similarity index 100% rename from wise-webapp/src/main/webapp/WEB-INF/views/init.jsp rename to wise-webapp/src/main/resources/views/init.jsp diff --git a/wise-webapp/src/main/webapp/WEB-INF/views/mindmapEditor.jsp b/wise-webapp/src/main/resources/views/mindmapEditor.jsp similarity index 100% rename from wise-webapp/src/main/webapp/WEB-INF/views/mindmapEditor.jsp rename to wise-webapp/src/main/resources/views/mindmapEditor.jsp diff --git a/wise-webapp/src/main/webapp/WEB-INF/views/mindmapViewonly.jsp b/wise-webapp/src/main/resources/views/mindmapViewonly.jsp similarity index 100% rename from wise-webapp/src/main/webapp/WEB-INF/views/mindmapViewonly.jsp rename to wise-webapp/src/main/resources/views/mindmapViewonly.jsp diff --git a/wise-webapp/src/main/webapp/WEB-INF/views/pageHeaders.jsf b/wise-webapp/src/main/resources/views/pageHeaders.jsf similarity index 100% rename from wise-webapp/src/main/webapp/WEB-INF/views/pageHeaders.jsf rename to wise-webapp/src/main/resources/views/pageHeaders.jsf diff --git a/wise-webapp/src/main/webapp/WEB-INF/views/reactInclude.jsp b/wise-webapp/src/main/resources/views/reactInclude.jsp similarity index 100% rename from wise-webapp/src/main/webapp/WEB-INF/views/reactInclude.jsp rename to wise-webapp/src/main/resources/views/reactInclude.jsp diff --git a/wise-webapp/src/main/webapp/META-INF/Context.xml b/wise-webapp/src/main/webapp/META-INF/Context.xml deleted file mode 100755 index 0af54be5..00000000 --- a/wise-webapp/src/main/webapp/META-INF/Context.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/wise-webapp/src/main/webapp/index.jsp b/wise-webapp/src/main/webapp/index.jsp deleted file mode 100644 index a444398c..00000000 --- a/wise-webapp/src/main/webapp/index.jsp +++ /dev/null @@ -1,3 +0,0 @@ -<% - response.sendRedirect("c/maps/"); -%> \ No newline at end of file From 079f8ac417a82eca28ccb9a509a0531b457bf071 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Mon, 27 Nov 2023 21:08:28 -0800 Subject: [PATCH 004/110] Fix MVC --- wise-webapp/pom.xml | 22 +- .../com/wisemapping/config/Application.java | 31 ++- .../wisemapping/config/HibernateConfig.java | 2 + .../wisemapping/config/SecurityConfig.java | 159 ------------- .../{MvcConfig.java => mvc/MvcAppConfig.java} | 28 ++- .../config/mvc/MvcSecurityConfig.java | 101 ++++++++ .../wisemapping/config/mvc/ServletConfig.java | 12 + .../config/rest/RestAppConfig.java | 44 ++++ .../wisemapping/rest/AccountController.java | 7 +- .../com/wisemapping/rest/AdminController.java | 2 +- .../com/wisemapping/rest/LabelController.java | 2 +- .../wisemapping/rest/MindmapController.java | 2 +- .../wisemapping/rest/OAuth2Controller.java | 2 +- .../com/wisemapping/rest/UserController.java | 2 +- .../AuthenticationSuccessHandler.java | 60 ----- .../security/UserDetailsService.java | 3 + .../service/MindmapServiceImpl.java | 1 - .../webmvc/MvcLoginController.java | 5 +- .../webmvc/MvcMindmapController.java | 30 +-- .../webmvc/MvcUsersController.java | 10 +- .../src/main/resources/application.properties | 3 + wise-webapp/src/main/resources/log4j2.xml | 7 +- .../resources/spring/wisemapping-common.xml | 11 - .../resources/spring/wisemapping-rest.xml | 9 - .../resources/spring/wisemapping-servlet.xml | 16 +- .../views => webapp/WEB-INF/jsp}/init.jsp | 0 .../WEB-INF/jsp}/mindmapEditor.jsp | 0 .../WEB-INF/jsp}/mindmapViewonly.jsp | 0 .../WEB-INF/jsp}/pageHeaders.jsf | 0 .../WEB-INF/jsp}/reactInclude.jsp | 0 wise-webapp/src/main/webapp/WEB-INF/web.xml | 222 +++++++++--------- 31 files changed, 351 insertions(+), 442 deletions(-) delete mode 100644 wise-webapp/src/main/java/com/wisemapping/config/SecurityConfig.java rename wise-webapp/src/main/java/com/wisemapping/config/{MvcConfig.java => mvc/MvcAppConfig.java} (63%) create mode 100644 wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcSecurityConfig.java create mode 100644 wise-webapp/src/main/java/com/wisemapping/config/mvc/ServletConfig.java create mode 100644 wise-webapp/src/main/java/com/wisemapping/config/rest/RestAppConfig.java delete mode 100644 wise-webapp/src/main/java/com/wisemapping/security/AuthenticationSuccessHandler.java delete mode 100644 wise-webapp/src/main/resources/spring/wisemapping-common.xml rename wise-webapp/src/main/{resources/views => webapp/WEB-INF/jsp}/init.jsp (100%) rename wise-webapp/src/main/{resources/views => webapp/WEB-INF/jsp}/mindmapEditor.jsp (100%) rename wise-webapp/src/main/{resources/views => webapp/WEB-INF/jsp}/mindmapViewonly.jsp (100%) rename wise-webapp/src/main/{resources/views => webapp/WEB-INF/jsp}/pageHeaders.jsf (100%) rename wise-webapp/src/main/{resources/views => webapp/WEB-INF/jsp}/reactInclude.jsp (100%) diff --git a/wise-webapp/pom.xml b/wise-webapp/pom.xml index 3e42f21d..7837066a 100644 --- a/wise-webapp/pom.xml +++ b/wise-webapp/pom.xml @@ -67,16 +67,12 @@ 12.0 compile - - - - - - - - - - + + org.apache.tomcat.embed + tomcat-embed-jasper + 10.1.9 + provided + org.postgresql postgresql @@ -195,6 +191,12 @@ spring-security-config ${org.springframework.addons} + + org.projectlombok + lombok + RELEASE + compile + diff --git a/wise-webapp/src/main/java/com/wisemapping/config/Application.java b/wise-webapp/src/main/java/com/wisemapping/config/Application.java index e22ae7ed..cb986831 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/Application.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/Application.java @@ -1,18 +1,35 @@ package com.wisemapping.config; -import org.springframework.boot.SpringApplication; +import com.wisemapping.config.mvc.MvcAppConfig; +import com.wisemapping.config.mvc.MvcSecurityConfig; +import com.wisemapping.config.mvc.ServletConfig; +import com.wisemapping.config.rest.RestAppConfig; +import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ImportResource; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.security.web.firewall.StrictHttpFirewall; -@EnableTransactionManagement @SpringBootApplication -@EnableJpaRepositories("com.wisemapping.model") -@ImportResource("classpath:spring/wisemapping-common.xml") +@ImportResource(value = {"classpath:spring/wisemapping-service.xml"}) +@ComponentScan({"com.wisemapping.security", "com.wisemapping.service", "com.wisemapping.dao", "com.wisemapping.util"}) public class Application { public static void main(String[] args) { - SpringApplication.run(Application.class, args); + + new SpringApplicationBuilder() + .parent(Application.class, HibernateConfig.class, MethodSecurityConfig.class).web(WebApplicationType.NONE) + .child(MvcAppConfig.class, MvcSecurityConfig.class, ServletConfig.class).web(WebApplicationType.SERVLET) + .sibling(RestAppConfig.class).web(WebApplicationType.SERVLET) + .run(args); + } + + @Bean + public StrictHttpFirewall httpFirewall() { + StrictHttpFirewall firewall = new StrictHttpFirewall(); + firewall.setAllowSemicolon(true); + return firewall; } } diff --git a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java index 8e25e9ce..29bf47d1 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java @@ -1,10 +1,12 @@ package com.wisemapping.config; import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement +@EnableJpaRepositories("com.wisemapping.model") public class HibernateConfig { // @Value("${database.hibernate.dialect}") // private String dbDialect; diff --git a/wise-webapp/src/main/java/com/wisemapping/config/SecurityConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/SecurityConfig.java deleted file mode 100644 index da8baa29..00000000 --- a/wise-webapp/src/main/java/com/wisemapping/config/SecurityConfig.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.wisemapping.config; - -import com.wisemapping.security.AuthenticationSuccessHandler; -import com.wisemapping.security.UserDetailsService; -import com.wisemapping.service.UserService; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.firewall.StrictHttpFirewall; -import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; -import org.springframework.web.servlet.handler.HandlerMappingIntrospector; - - -@Configuration -@EnableWebSecurity -public class SecurityConfig { - @Autowired - UserService userService; - - @Value("${admin.user}") - String adminUser; - - @Bean - public StrictHttpFirewall httpFirewall() { - StrictHttpFirewall firewall = new StrictHttpFirewall(); - firewall.setAllowSemicolon(true); - return firewall; - } - @Bean - @Order(1) - public SecurityFilterChain embeddedDisabledXOrigin(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception { - final MvcRequestMatcher.Builder mvcMatcher = new MvcRequestMatcher.Builder(introspector).servletPath("/c"); - http - .securityMatchers((matchers) -> - matchers.requestMatchers(mvcMatcher.pattern(("/maps/*/embed")))) - .authorizeHttpRequests( - (auth) -> auth.requestMatchers(mvcMatcher.pattern("/maps/*/embed")).permitAll()) - .headers((header -> header.frameOptions() - .disable() - )) - .csrf(AbstractHttpConfigurer::disable); - - return http.build(); - } - - @Bean - @Order(2) - SecurityFilterChain apiSecurityFilterChain(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception { - final MvcRequestMatcher.Builder serviceMapper = new MvcRequestMatcher.Builder(introspector).servletPath("/service"); - return http - .securityMatchers((matchers) -> - matchers.requestMatchers(serviceMapper.pattern(("/**")))) - .authorizeHttpRequests(auth -> - auth - .requestMatchers(serviceMapper.pattern("/users/")).permitAll() - .requestMatchers(serviceMapper.pattern("/users/resetPassword")).permitAll() - .requestMatchers(serviceMapper.pattern("/oauth2/googlecallback")).permitAll() - .requestMatchers(serviceMapper.pattern("/oauth2/confirmaccountsync")).permitAll() - .requestMatchers(serviceMapper.pattern("/admin/**")).hasAnyRole("ADMIN") - .requestMatchers(serviceMapper.pattern("/**")).hasAnyRole("USER", "ADMIN") - ) - .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - .httpBasic(httpBasic -> { - }) - .csrf(AbstractHttpConfigurer::disable) - .build(); - } - - @Bean - @Order(3) - public SecurityFilterChain mvcFilterChain(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception { - final AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler(); - authenticationSuccessHandler.setAlwaysUseDefaultTargetUrl(false); - authenticationSuccessHandler.setDefaultTargetUrl("/c/maps/"); - - final MvcRequestMatcher.Builder restfullMapper = new MvcRequestMatcher.Builder(introspector).servletPath("/c/restful"); - final MvcRequestMatcher.Builder mvcMatcher = new MvcRequestMatcher.Builder(introspector).servletPath("/c"); - - http - .securityMatchers((matchers) -> - matchers.requestMatchers(restfullMapper.pattern(("/**"))). - requestMatchers(mvcMatcher.pattern(("/**")))) - .authorizeHttpRequests( - (auth) -> - auth - .requestMatchers(mvcMatcher.pattern("/login")).permitAll() - .requestMatchers(mvcMatcher.pattern("/logout")).permitAll() - - .requestMatchers(mvcMatcher.pattern("/registration")).permitAll() - .requestMatchers(mvcMatcher.pattern("/registration-success")).permitAll() - .requestMatchers(mvcMatcher.pattern("/registration-google")).permitAll() - - .requestMatchers(mvcMatcher.pattern("/forgot-password")).permitAll() - .requestMatchers(mvcMatcher.pattern("/forgot-password-success")).permitAll() - .requestMatchers(mvcMatcher.pattern("/maps/*/try")).permitAll() - .requestMatchers(mvcMatcher.pattern("/maps/*/public")).permitAll() - .requestMatchers(restfullMapper.pattern("/maps/*/document/xml-pub")).permitAll() - .requestMatchers(mvcMatcher.pattern("/**")).hasAnyRole("USER", "ADMIN") - .requestMatchers(restfullMapper.pattern("/**")).hasAnyRole("USER", "ADMIN") - .anyRequest().authenticated()) - .formLogin((loginForm) -> - loginForm.loginPage("/c/login") - .loginProcessingUrl("/c/perform-login") - .defaultSuccessUrl("/c/maps/") - .failureUrl("/c/login?login_error=2")) - .logout((logout) -> - logout - .logoutUrl("/c/logout") - .logoutSuccessUrl("/c/login") - .invalidateHttpSession(true) - .deleteCookies("JSESSIONID") - .permitAll() - ).rememberMe(remember -> - remember - .tokenValiditySeconds(2419200) - .rememberMeParameter("remember-me" - ).authenticationSuccessHandler(authenticationSuccessHandler) - ).headers((header -> header.frameOptions() - .disable() - )) - .csrf((csrf) -> - csrf.ignoringRequestMatchers(mvcMatcher.pattern("/logout"))); - - return http.build(); - } - - @Bean - @Order(4) - public SecurityFilterChain shareResourcesFilterChain(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception { - final MvcRequestMatcher.Builder restfullMapper = new MvcRequestMatcher.Builder(introspector); - - return http.authorizeHttpRequests( - (auth) -> - auth.requestMatchers(restfullMapper.pattern("/static/**")).permitAll(). - requestMatchers(restfullMapper.pattern("/css/**")).permitAll(). - requestMatchers(restfullMapper.pattern("/js/**")).permitAll(). - requestMatchers(restfullMapper.pattern("/images/**")).permitAll(). - requestMatchers(restfullMapper.pattern("/*")).permitAll() - ).build(); - } - - - - @Bean - public UserDetailsService userDetailsService() { - final UserDetailsService result = new UserDetailsService(); - result.setUserService(userService); - result.setAdminUser(adminUser); - return result; - } -} diff --git a/wise-webapp/src/main/java/com/wisemapping/config/MvcConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java similarity index 63% rename from wise-webapp/src/main/java/com/wisemapping/config/MvcConfig.java rename to wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java index 7c86002c..1e923311 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/MvcConfig.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java @@ -1,30 +1,34 @@ -package com.wisemapping.config; +package com.wisemapping.config.mvc; +import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.ImportResource; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; -@Configuration + +@SpringBootApplication @EnableWebMvc -public class MvcConfig implements WebMvcConfigurer { - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry - .addResourceHandler("/**") - .addResourceLocations("classpath:/public/"); - } +@ImportResource(value = {"classpath:spring/wisemapping-servlet.xml"}) +@ComponentScan("com.wisemapping.webmvc") +public class MvcAppConfig implements WebMvcConfigurer { +// @Override +// public void addResourceHandlers(ResourceHandlerRegistry registry) { +// registry +// .addResourceHandler("/**") +// .addResourceLocations("classpath:/public/"); +// } @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); - resolver.setPrefix("/views/"); + resolver.setPrefix("/WEB-INF/jsp/"); resolver.setSuffix(".jsp"); resolver.setViewClass(JstlView.class); return resolver; diff --git a/wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcSecurityConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcSecurityConfig.java new file mode 100644 index 00000000..d90cbdd1 --- /dev/null +++ b/wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcSecurityConfig.java @@ -0,0 +1,101 @@ +package com.wisemapping.config.mvc; + +import org.jetbrains.annotations.NotNull; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +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.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; + + +@Configuration +@EnableWebSecurity +public class MvcSecurityConfig { + + @Bean + @Order(1) + public SecurityFilterChain embeddedDisabledXOrigin(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception { + final MvcRequestMatcher.Builder matcher = new MvcRequestMatcher.Builder(introspector); + + http + .securityMatchers((matchers) -> + matchers.requestMatchers(matcher.pattern("c/maps/*/embed"))) + .authorizeHttpRequests( + (auth) -> auth.requestMatchers(matcher.pattern(("c/maps/*/embed"))).permitAll()) + .headers((header -> header.frameOptions() + .disable() + )) + .csrf(AbstractHttpConfigurer::disable); + + return http.build(); + } + + @Bean + @Order(2) + public SecurityFilterChain mvcFilterChain(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception { + final MvcRequestMatcher.Builder matcher = new MvcRequestMatcher.Builder(introspector); + http + .securityMatchers((matchers) -> + matchers.requestMatchers(matcher.pattern("/c/**"))) + .authorizeHttpRequests( + (auth) -> + auth + .requestMatchers(matcher.pattern("/c/login")).permitAll() + .requestMatchers(matcher.pattern("/c/logout")).permitAll() + .requestMatchers(matcher.pattern("/c/registration")).permitAll() + .requestMatchers(matcher.pattern("/c/registration-success")).permitAll() + .requestMatchers(matcher.pattern("/c/registration-google")).permitAll() + + .requestMatchers(matcher.pattern("/c/forgot-password")).permitAll() + .requestMatchers(matcher.pattern("/c/forgot-password-success")).permitAll() + .requestMatchers(matcher.pattern("/c/maps/*/try")).permitAll() + .requestMatchers(matcher.pattern("/c/maps/*/public")).permitAll() + .requestMatchers(matcher.pattern("/c/**")).hasAnyRole("USER", "ADMIN") + .anyRequest().authenticated()) + .formLogin((loginForm) -> + loginForm.loginPage("/c/login") + .loginProcessingUrl("/c/perform-login") + .defaultSuccessUrl("/c/maps/") + .failureUrl("/c/login?login_error=2")) + .logout((logout) -> + logout + .logoutUrl("/c/logout") + .logoutSuccessUrl("/c/login") + .invalidateHttpSession(true) + .deleteCookies("JSESSIONID") + .permitAll() + ).rememberMe(remember -> + remember + .tokenValiditySeconds(2419200) + .rememberMeParameter("remember-me" + ) + ).headers((header -> header.frameOptions() + .disable() + )) + .csrf((csrf) -> + csrf.ignoringRequestMatchers(matcher.pattern("/c/logout"))); + + return http.build(); + } + + @Bean + @Order(3) + public SecurityFilterChain shareResourcesFilterChain(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception { + final MvcRequestMatcher.Builder matcher = new MvcRequestMatcher.Builder(introspector); + + return http.authorizeHttpRequests( + (auth) -> + auth.requestMatchers(matcher.pattern("/static/**")).permitAll(). + requestMatchers(matcher.pattern("/css/**")).permitAll(). + requestMatchers(matcher.pattern("/js/**")).permitAll(). + // @todo: Wht this is required ... + requestMatchers(matcher.pattern("/WEB-INF/jsp/*.jsp")).permitAll(). + requestMatchers(matcher.pattern("/images/**")).permitAll(). + requestMatchers(matcher.pattern("/*")).permitAll() + ).build(); + } +} diff --git a/wise-webapp/src/main/java/com/wisemapping/config/mvc/ServletConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/mvc/ServletConfig.java new file mode 100644 index 00000000..9bad0c5c --- /dev/null +++ b/wise-webapp/src/main/java/com/wisemapping/config/mvc/ServletConfig.java @@ -0,0 +1,12 @@ +package com.wisemapping.config.mvc; + +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ServletConfig implements WebServerFactoryCustomizer { + public void customize(ConfigurableServletWebServerFactory factory){ + factory.setPort(8081); + } +} \ No newline at end of file diff --git a/wise-webapp/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/rest/RestAppConfig.java new file mode 100644 index 00000000..d97f3aed --- /dev/null +++ b/wise-webapp/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -0,0 +1,44 @@ +package com.wisemapping.config.rest; + +import org.jetbrains.annotations.NotNull; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.core.annotation.Order; +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.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; + + +@SpringBootApplication +@EnableWebSecurity +@ComponentScan("com.wisemapping.rest") +public class RestAppConfig { + @Bean + @Order(2) + SecurityFilterChain apiSecurityFilterChain(@NotNull final HttpSecurity http, @NotNull final HandlerMappingIntrospector introspector) throws Exception { + final MvcRequestMatcher.Builder matcher = new MvcRequestMatcher.Builder(introspector).servletPath("/service"); + return http + .securityMatchers((matchers) -> + matchers.requestMatchers(matcher.pattern(("/**")))) + .authorizeHttpRequests(auth -> + auth + .requestMatchers(matcher.pattern("/users/")).permitAll() + .requestMatchers(matcher.pattern("/users/resetPassword")).permitAll() + .requestMatchers(matcher.pattern("/oauth2/googlecallback")).permitAll() + .requestMatchers(matcher.pattern("/oauth2/confirmaccountsync")).permitAll() + .requestMatchers(matcher.pattern("/admin/**")).hasAnyRole("ADMIN") + .requestMatchers(matcher.pattern("/**")).hasAnyRole("USER", "ADMIN") + ) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .httpBasic(httpBasic -> { + }) + .csrf(AbstractHttpConfigurer::disable) + .build(); + } + +} diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/AccountController.java b/wise-webapp/src/main/java/com/wisemapping/rest/AccountController.java index 571d96e2..e8c8dfb3 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/AccountController.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/AccountController.java @@ -34,14 +34,11 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.*; import java.util.List; -@Controller +@RestController @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") public class AccountController extends BaseController { @Qualifier("userService") diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/AdminController.java b/wise-webapp/src/main/java/com/wisemapping/rest/AdminController.java index 71cf2700..e849c4f1 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/AdminController.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/AdminController.java @@ -38,7 +38,7 @@ import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; -@Controller +@RestController @PreAuthorize("isAuthenticated() and hasRole('ROLE_ADMIN')") public class AdminController extends BaseController { @Qualifier("userService") diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/LabelController.java b/wise-webapp/src/main/java/com/wisemapping/rest/LabelController.java index 9a8078c1..284d90c5 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/LabelController.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/LabelController.java @@ -40,7 +40,7 @@ import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletResponse; import java.util.List; -@Controller +@RestController @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") public class LabelController extends BaseController { diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/MindmapController.java b/wise-webapp/src/main/java/com/wisemapping/rest/MindmapController.java index a3aea80e..cdb69ffb 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/MindmapController.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/MindmapController.java @@ -49,7 +49,7 @@ import java.util.*; import java.util.stream.Collectors; -@Controller +@RestController @Transactional(propagation = Propagation.REQUIRED) public class MindmapController extends BaseController { private final Logger logger = LogManager.getLogger(); diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/OAuth2Controller.java b/wise-webapp/src/main/java/com/wisemapping/rest/OAuth2Controller.java index 9130a4b5..7427070d 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/OAuth2Controller.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/OAuth2Controller.java @@ -38,7 +38,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -@Controller +@RestController @CrossOrigin public class OAuth2Controller extends BaseController { @Qualifier("userService") diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/UserController.java b/wise-webapp/src/main/java/com/wisemapping/rest/UserController.java index 5791fed8..6208e365 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/UserController.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/UserController.java @@ -47,7 +47,7 @@ import jakarta.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.List; -@Controller +@RestController @CrossOrigin public class UserController extends BaseController { diff --git a/wise-webapp/src/main/java/com/wisemapping/security/AuthenticationSuccessHandler.java b/wise-webapp/src/main/java/com/wisemapping/security/AuthenticationSuccessHandler.java deleted file mode 100644 index 2e3945b6..00000000 --- a/wise-webapp/src/main/java/com/wisemapping/security/AuthenticationSuccessHandler.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright [2022] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.wisemapping.security; - -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import org.springframework.security.web.savedrequest.HttpSessionRequestCache; -import org.springframework.security.web.savedrequest.RequestCache; -import org.springframework.security.web.savedrequest.SavedRequest; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; - - -public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { - private final RequestCache cache; - - public AuthenticationSuccessHandler() { - cache = new HttpSessionRequestCache(); - this.setRequestCache(cache); - } - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { - - SavedRequest savedRequest = cache.getRequest(request, response); - if (savedRequest != null && savedRequest.getRedirectUrl().contains("c/restful")) { - cache.removeRequest(request, response); - } - super.onAuthenticationSuccess(request, response, authentication); - } - - @Override - protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) { - String url = super.determineTargetUrl(request, response); - // Prevent redirecting to rest services on login ... - if (url.contains("c/restful")) { - url = this.getDefaultTargetUrl(); - } - return url; - } - -} \ No newline at end of file diff --git a/wise-webapp/src/main/java/com/wisemapping/security/UserDetailsService.java b/wise-webapp/src/main/java/com/wisemapping/security/UserDetailsService.java index 42725a89..e6d04030 100644 --- a/wise-webapp/src/main/java/com/wisemapping/security/UserDetailsService.java +++ b/wise-webapp/src/main/java/com/wisemapping/security/UserDetailsService.java @@ -24,6 +24,7 @@ import com.wisemapping.service.UserService; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.DataAccessException; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; @@ -34,6 +35,8 @@ public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService { @Autowired private UserService userService; + + @Value("${admin.user}") private String adminUser; @Override diff --git a/wise-webapp/src/main/java/com/wisemapping/service/MindmapServiceImpl.java b/wise-webapp/src/main/java/com/wisemapping/service/MindmapServiceImpl.java index 41e20091..e7729265 100755 --- a/wise-webapp/src/main/java/com/wisemapping/service/MindmapServiceImpl.java +++ b/wise-webapp/src/main/java/com/wisemapping/service/MindmapServiceImpl.java @@ -54,7 +54,6 @@ public class MindmapServiceImpl @Autowired private NotificationService notificationService; - @Value("${admin.user}") private String adminUser; final private LockManager lockManager; diff --git a/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcLoginController.java b/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcLoginController.java index b21c279c..6f12760d 100644 --- a/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcLoginController.java +++ b/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcLoginController.java @@ -31,10 +31,8 @@ import org.springframework.web.servlet.ModelAndView; @PreAuthorize("permitAll()") public class MvcLoginController { -// @Value("${database.driver}") - private String driver; - @RequestMapping(value = "login", method = RequestMethod.GET) + @RequestMapping(value = "c/login", method = RequestMethod.GET) protected ModelAndView showLoginPage() { final User user = Utils.getUser(false); ModelAndView result; @@ -42,7 +40,6 @@ public class MvcLoginController { result = new ModelAndView("forward:/c/maps/"); } else { result = new ModelAndView("reactInclude"); - result.addObject("isHsql", driver.contains("hsql")); } return result; } diff --git a/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcMindmapController.java b/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcMindmapController.java index bfca1266..0d650692 100644 --- a/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcMindmapController.java +++ b/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcMindmapController.java @@ -55,7 +55,7 @@ public class MvcMindmapController { @Autowired private MindmapService mindmapService; - @RequestMapping(value = "maps/{id}/print") + @RequestMapping(value = "c/maps/{id}/print") public String showPrintPage(@PathVariable int id, @NotNull Model model) throws MapCouldNotFoundException, AccessDeniedSecurityException { final MindMapBean mindmap = findMindmapBean(id); @@ -67,12 +67,12 @@ public class MvcMindmapController { return "mindmapViewonly"; } - @RequestMapping(value = "maps/") + @RequestMapping(value = "c/maps/") public String showListPage(@NotNull Model model) { return "reactInclude"; } - @RequestMapping(value = "maps/{id}/edit", method = RequestMethod.GET) + @RequestMapping(value = "c/maps/{id}/edit", method = RequestMethod.GET) public String showMindmapEditorPage(@PathVariable int id, @NotNull Model model) throws WiseMappingException { return showEditorPage(id, model, true); } @@ -104,26 +104,26 @@ public class MvcMindmapController { return "mindmapEditor"; } - @RequestMapping(value = "maps/{id}/view", method = RequestMethod.GET) + @RequestMapping(value = "c/maps/{id}/view", method = RequestMethod.GET) public String showMindmapViewerPage(@PathVariable int id, @NotNull Model model) throws WiseMappingException { final String result = showPrintPage(id, model); return result; } - @RequestMapping(value = "maps/{id}/try", method = RequestMethod.GET) + @RequestMapping(value = "c/maps/{id}/try", method = RequestMethod.GET) @PreAuthorize("permitAll()") public String showMindmapTryPage(@PathVariable int id, @NotNull Model model) throws WiseMappingException { return showEditorPage(id, model, false); } - @RequestMapping(value = "maps/{id}/{hid}/view", method = RequestMethod.GET) + @RequestMapping(value = "c/maps/{id}/{hid}/view", method = RequestMethod.GET) public String showMindmapViewerRevPage(@PathVariable int id, @PathVariable int hid, @NotNull Model model) throws WiseMappingException { final String result = showPrintPage(id, model); model.addAttribute("hid", String.valueOf(hid)); return result; } - @RequestMapping(value = "maps/{id}/embed") + @RequestMapping(value = "c/maps/{id}/embed") @PreAuthorize("permitAll()") public ModelAndView showEmbeddedPage(@PathVariable int id, @RequestParam(required = false) Float zoom) throws MapCouldNotFoundException, MapNotPublicSecurityException, AccessDeniedSecurityException { if (!mindmapService.isMindmapPublic(id)) { @@ -138,7 +138,7 @@ public class MvcMindmapController { return view; } - @RequestMapping(value = "maps/{id}/public", method = RequestMethod.GET) + @RequestMapping(value = "c/maps/{id}/public", method = RequestMethod.GET) @PreAuthorize("permitAll()") public String showPublicViewPage(@PathVariable int id, @NotNull Model model) throws WiseMappingException { if (!mindmapService.isMindmapPublic(id)) { @@ -147,20 +147,6 @@ public class MvcMindmapController { return this.showPrintPage(id, model); } - @Deprecated - @RequestMapping(value = "publicView", method = RequestMethod.GET) - @PreAuthorize("permitAll()") - public String showPublicViewPageLegacy(@RequestParam(required = true) int mapId) { - return "redirect:maps/" + mapId + "/public"; - } - - @Deprecated - @RequestMapping(value = "embeddedView", method = RequestMethod.GET) - @PreAuthorize("permitAll()") - public String showPublicViewLegacyPage(@RequestParam(required = true) int mapId, @RequestParam(required = false) int zoom) { - return "redirect:maps/" + mapId + "/embed?zoom=" + zoom; - } - @NotNull private Mindmap findMindmap(int mapId) throws MapCouldNotFoundException { final Mindmap result = mindmapService.findMindmapById(mapId); diff --git a/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcUsersController.java b/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcUsersController.java index 17d4215d..d626c20d 100644 --- a/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcUsersController.java +++ b/wise-webapp/src/main/java/com/wisemapping/webmvc/MvcUsersController.java @@ -35,31 +35,31 @@ public class MvcUsersController { @Autowired private UserService userService; - @RequestMapping(value = "forgot-password", method = RequestMethod.GET) + @RequestMapping(value = "c/forgot-password", method = RequestMethod.GET) @PreAuthorize("permitAll()") public ModelAndView showResetPasswordPage() { return new ModelAndView("reactInclude"); } - @RequestMapping(value = "registration-google", method = RequestMethod.GET) + @RequestMapping(value = "c/registration-google", method = RequestMethod.GET) @PreAuthorize("permitAll()") public ModelAndView processGoogleCallback() { return new ModelAndView("reactInclude"); } - @RequestMapping(value = "registration", method = RequestMethod.GET) + @RequestMapping(value = "c/registration", method = RequestMethod.GET) @PreAuthorize("permitAll()") public ModelAndView showRegistrationPage() { return new ModelAndView("reactInclude"); } - @RequestMapping(value = "registration-success", method = RequestMethod.GET) + @RequestMapping(value = "c/registration-success", method = RequestMethod.GET) @PreAuthorize("permitAll()") public ModelAndView showRegistrationSuccess() { return new ModelAndView("reactInclude"); } - @RequestMapping(value = "forgot-password-success", method = RequestMethod.GET) + @RequestMapping(value = "c/forgot-password-success", method = RequestMethod.GET) @PreAuthorize("permitAll()") public ModelAndView showResetPasswordSuccess() { return new ModelAndView("reactInclude"); diff --git a/wise-webapp/src/main/resources/application.properties b/wise-webapp/src/main/resources/application.properties index fbd8c1f9..be2684c2 100755 --- a/wise-webapp/src/main/resources/application.properties +++ b/wise-webapp/src/main/resources/application.properties @@ -179,3 +179,6 @@ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect spring.jpa.open-in-view=true spring.h2.console.enabled=true spring.h2.console.path=/h2-ui + + +logging.level.root=TRACE diff --git a/wise-webapp/src/main/resources/log4j2.xml b/wise-webapp/src/main/resources/log4j2.xml index ca024d64..41d209d6 100644 --- a/wise-webapp/src/main/resources/log4j2.xml +++ b/wise-webapp/src/main/resources/log4j2.xml @@ -1,14 +1,9 @@ - + - - - %d %p %c{1.} [%t] %m%n - - diff --git a/wise-webapp/src/main/resources/spring/wisemapping-common.xml b/wise-webapp/src/main/resources/spring/wisemapping-common.xml deleted file mode 100644 index c7c41d44..00000000 --- a/wise-webapp/src/main/resources/spring/wisemapping-common.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - diff --git a/wise-webapp/src/main/resources/spring/wisemapping-rest.xml b/wise-webapp/src/main/resources/spring/wisemapping-rest.xml index fa3b1967..8ee1830c 100644 --- a/wise-webapp/src/main/resources/spring/wisemapping-rest.xml +++ b/wise-webapp/src/main/resources/spring/wisemapping-rest.xml @@ -49,13 +49,4 @@ - - - - - - - - - \ No newline at end of file diff --git a/wise-webapp/src/main/resources/spring/wisemapping-servlet.xml b/wise-webapp/src/main/resources/spring/wisemapping-servlet.xml index 1c93d70d..136df01d 100644 --- a/wise-webapp/src/main/resources/spring/wisemapping-servlet.xml +++ b/wise-webapp/src/main/resources/spring/wisemapping-servlet.xml @@ -1,18 +1,12 @@ - - @@ -23,12 +17,4 @@ - - - - - - - - diff --git a/wise-webapp/src/main/resources/views/init.jsp b/wise-webapp/src/main/webapp/WEB-INF/jsp/init.jsp similarity index 100% rename from wise-webapp/src/main/resources/views/init.jsp rename to wise-webapp/src/main/webapp/WEB-INF/jsp/init.jsp diff --git a/wise-webapp/src/main/resources/views/mindmapEditor.jsp b/wise-webapp/src/main/webapp/WEB-INF/jsp/mindmapEditor.jsp similarity index 100% rename from wise-webapp/src/main/resources/views/mindmapEditor.jsp rename to wise-webapp/src/main/webapp/WEB-INF/jsp/mindmapEditor.jsp diff --git a/wise-webapp/src/main/resources/views/mindmapViewonly.jsp b/wise-webapp/src/main/webapp/WEB-INF/jsp/mindmapViewonly.jsp similarity index 100% rename from wise-webapp/src/main/resources/views/mindmapViewonly.jsp rename to wise-webapp/src/main/webapp/WEB-INF/jsp/mindmapViewonly.jsp diff --git a/wise-webapp/src/main/resources/views/pageHeaders.jsf b/wise-webapp/src/main/webapp/WEB-INF/jsp/pageHeaders.jsf similarity index 100% rename from wise-webapp/src/main/resources/views/pageHeaders.jsf rename to wise-webapp/src/main/webapp/WEB-INF/jsp/pageHeaders.jsf diff --git a/wise-webapp/src/main/resources/views/reactInclude.jsp b/wise-webapp/src/main/webapp/WEB-INF/jsp/reactInclude.jsp similarity index 100% rename from wise-webapp/src/main/resources/views/reactInclude.jsp rename to wise-webapp/src/main/webapp/WEB-INF/jsp/reactInclude.jsp diff --git a/wise-webapp/src/main/webapp/WEB-INF/web.xml b/wise-webapp/src/main/webapp/WEB-INF/web.xml index 921ab35f..42ab6c1b 100644 --- a/wise-webapp/src/main/webapp/WEB-INF/web.xml +++ b/wise-webapp/src/main/webapp/WEB-INF/web.xml @@ -1,131 +1,131 @@ - + - + + + + - - charsetFilter - org.springframework.web.filter.CharacterEncodingFilter - - encoding - UTF-8 - - + + + + + + + + - + - - jakarta.servlet.jsp.jstl.fmt.localizationContext - messages - + + + + - - contextConfigLocation - - classpath:spring/wisemapping-common.xml - - + + + + + + - - contextInitializerClasses - com.wisemapping.webmvc.ApplicationContextInitializer - - - + + + + + + + + + + - - com.wisemapping.listener.UnlockOnExpireListener - + + + - - hibernate - org.springframework.orm.hibernate5.support.OpenSessionInViewFilter - - singleSession - true - - - sessionFactoryBeanName - sessionFactory - - + + + + + + + + + + + + - - springSecurityFilterChain - org.springframework.web.filter.DelegatingFilterProxy - + + + + - - springSecurityFilterChain - /* - + + + + - - hibernate - /* - + + + + - - charsetFilter - /* - + + + + - - org.springframework.web.context.ContextLoaderListener - + + + - - mvc-servlet - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - - classpath:spring/wisemapping-servlet.xml - - - 1 - + + + + + + + + + + + - - mvc-rest - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - - classpath:spring/wisemapping-rest.xml - - - 1 - + + + + + + + + + + + - - mvc-servlet - /c/* - + + + + - - mvc-rest - /service/* - + + + + - - mvc-rest - /c/restful/* - + + + + - - - index.jsp - - - - 1440 - - \ No newline at end of file + + + + + + + + + \ No newline at end of file From fa06852806904044bee5b8a16164bd2f868f336b Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Mon, 27 Nov 2023 21:47:22 -0800 Subject: [PATCH 005/110] Add static resources. --- .../com/wisemapping/config/mvc/MvcAppConfig.java | 13 +++++++------ .../src/main/resources/application.properties | 2 +- .../src/main/resources/public/static/mindplot | 1 + wise-webapp/src/main/resources/public/static/webapp | 1 + wise-webapp/src/main/webapp/static/mindplot | 1 - wise-webapp/src/main/webapp/static/webapp | 1 - 6 files changed, 10 insertions(+), 9 deletions(-) create mode 120000 wise-webapp/src/main/resources/public/static/mindplot create mode 120000 wise-webapp/src/main/resources/public/static/webapp delete mode 120000 wise-webapp/src/main/webapp/static/mindplot delete mode 120000 wise-webapp/src/main/webapp/static/webapp diff --git a/wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java index 1e923311..6dfaaad2 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java @@ -7,6 +7,7 @@ import org.springframework.context.annotation.ImportResource; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; @@ -18,12 +19,12 @@ import org.springframework.web.servlet.view.JstlView; @ImportResource(value = {"classpath:spring/wisemapping-servlet.xml"}) @ComponentScan("com.wisemapping.webmvc") public class MvcAppConfig implements WebMvcConfigurer { -// @Override -// public void addResourceHandlers(ResourceHandlerRegistry registry) { -// registry -// .addResourceHandler("/**") -// .addResourceLocations("classpath:/public/"); -// } + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry + .addResourceHandler("/**") + .addResourceLocations("classpath:/public/"); + } @Bean public ViewResolver viewResolver() { diff --git a/wise-webapp/src/main/resources/application.properties b/wise-webapp/src/main/resources/application.properties index be2684c2..6b3f60ee 100755 --- a/wise-webapp/src/main/resources/application.properties +++ b/wise-webapp/src/main/resources/application.properties @@ -181,4 +181,4 @@ spring.h2.console.enabled=true spring.h2.console.path=/h2-ui -logging.level.root=TRACE +logging.level.root=DEBUG diff --git a/wise-webapp/src/main/resources/public/static/mindplot b/wise-webapp/src/main/resources/public/static/mindplot new file mode 120000 index 00000000..61ad9a4e --- /dev/null +++ b/wise-webapp/src/main/resources/public/static/mindplot @@ -0,0 +1 @@ +../../../../../../wise-ui/target/wisemapping-mindplot/package/dist \ No newline at end of file diff --git a/wise-webapp/src/main/resources/public/static/webapp b/wise-webapp/src/main/resources/public/static/webapp new file mode 120000 index 00000000..240a1953 --- /dev/null +++ b/wise-webapp/src/main/resources/public/static/webapp @@ -0,0 +1 @@ +../../../../../../wise-ui/target/wisemapping-webapp/package/dist \ No newline at end of file diff --git a/wise-webapp/src/main/webapp/static/mindplot b/wise-webapp/src/main/webapp/static/mindplot deleted file mode 120000 index 351e6f9d..00000000 --- a/wise-webapp/src/main/webapp/static/mindplot +++ /dev/null @@ -1 +0,0 @@ -../../../../../wise-ui/target/wisemapping-mindplot/package/dist \ No newline at end of file diff --git a/wise-webapp/src/main/webapp/static/webapp b/wise-webapp/src/main/webapp/static/webapp deleted file mode 120000 index 7173cbf4..00000000 --- a/wise-webapp/src/main/webapp/static/webapp +++ /dev/null @@ -1 +0,0 @@ -../../../../../wise-ui/target/wisemapping-webapp/package/dist \ No newline at end of file From e1b517f657b6edaec597be5b4fc40274752348a4 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Mon, 4 Dec 2023 20:00:06 -0800 Subject: [PATCH 006/110] Add db creation. --- config/database/hsql/drop-schemas.sql | 1 - wise-webapp/db/wisemapping.properties | 5 + wise-webapp/db/wisemapping.script | 46 +++++++++ wise-webapp/pom.xml | 96 ------------------- .../com/wisemapping/config/Application.java | 8 +- .../wisemapping/config/HibernateConfig.java | 30 ------ .../com/wisemapping/dao/LabelManagerImpl.java | 3 +- .../com/wisemapping/dao/UserManagerImpl.java | 7 +- .../src/main/resources/application.properties | 55 +++-------- .../src/main/resources/data-hsqldb.sql | 0 .../src/main/resources/schema-hsqldb.sql | 0 11 files changed, 74 insertions(+), 177 deletions(-) delete mode 100644 config/database/hsql/drop-schemas.sql create mode 100644 wise-webapp/db/wisemapping.properties create mode 100644 wise-webapp/db/wisemapping.script rename config/database/hsql/apopulate-schemas.sql => wise-webapp/src/main/resources/data-hsqldb.sql (100%) rename config/database/hsql/create-schemas.sql => wise-webapp/src/main/resources/schema-hsqldb.sql (100%) diff --git a/config/database/hsql/drop-schemas.sql b/config/database/hsql/drop-schemas.sql deleted file mode 100644 index 77bf9e7b..00000000 --- a/config/database/hsql/drop-schemas.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE IF EXISTS ACCESS_AUDITORY; DROP TABLE IF EXISTS COLLABORATION; DROP TABLE IF EXISTS COLLABORATION_PROPERTIES; DROP TABLE IF EXISTS MINDMAP_HISTORY; DROP TABLE IF EXISTS R_LABEL_MINDMAP; DROP TABLE IF EXISTS LABEL; DROP TABLE IF EXISTS MINDMAP; DROP TABLE IF EXISTS USER; DROP TABLE IF EXISTS COLLABORATOR; COMMIT; \ No newline at end of file diff --git a/wise-webapp/db/wisemapping.properties b/wise-webapp/db/wisemapping.properties new file mode 100644 index 00000000..456f39de --- /dev/null +++ b/wise-webapp/db/wisemapping.properties @@ -0,0 +1,5 @@ +#HSQL Database Engine 2.7.1 +#Mon Nov 27 22:17:59 PST 2023 +modified=yes +tx_timestamp=270 +version=2.7.1 diff --git a/wise-webapp/db/wisemapping.script b/wise-webapp/db/wisemapping.script new file mode 100644 index 00000000..14464be6 --- /dev/null +++ b/wise-webapp/db/wisemapping.script @@ -0,0 +1,46 @@ +SET DATABASE UNIQUE NAME HSQLDB8C147822D0 +SET DATABASE DEFAULT RESULT MEMORY ROWS 0 +SET DATABASE EVENT LOG LEVEL 0 +SET DATABASE TRANSACTION CONTROL LOCKS +SET DATABASE DEFAULT ISOLATION LEVEL READ COMMITTED +SET DATABASE TRANSACTION ROLLBACK ON CONFLICT TRUE +SET DATABASE TEXT TABLE DEFAULTS '' +SET DATABASE SQL NAMES FALSE +SET DATABASE SQL RESTRICT EXEC FALSE +SET DATABASE SQL REFERENCES FALSE +SET DATABASE SQL SIZE TRUE +SET DATABASE SQL TYPES FALSE +SET DATABASE SQL TDC DELETE TRUE +SET DATABASE SQL TDC UPDATE TRUE +SET DATABASE SQL SYS INDEX NAMES TRUE +SET DATABASE SQL CONCAT NULLS TRUE +SET DATABASE SQL UNIQUE NULLS TRUE +SET DATABASE SQL CONVERT TRUNCATE TRUE +SET DATABASE SQL AVG SCALE 0 +SET DATABASE SQL DOUBLE NAN TRUE +SET FILES WRITE DELAY 500 MILLIS +SET FILES BACKUP INCREMENT TRUE +SET FILES CACHE SIZE 10000 +SET FILES CACHE ROWS 50000 +SET FILES SCALE 32 +SET FILES LOB SCALE 32 +SET FILES DEFRAG 0 +SET FILES NIO TRUE +SET FILES NIO SIZE 256 +SET FILES LOG TRUE +SET FILES LOG SIZE 50 +SET FILES CHECK 270 +SET DATABASE COLLATION "SQL_TEXT" PAD SPACE +CREATE USER SA PASSWORD DIGEST 'd41d8cd98f00b204e9800998ecf8427e' +ALTER USER SA SET LOCAL TRUE +CREATE SCHEMA PUBLIC AUTHORIZATION DBA +ALTER SEQUENCE SYSTEM_LOBS.LOB_ID RESTART WITH 1 +SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CARDINAL_NUMBER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.YES_OR_NO TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CHARACTER_DATA TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.SQL_IDENTIFIER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.TIME_STAMP TO PUBLIC +GRANT DBA TO SA +SET SCHEMA SYSTEM_LOBS +INSERT INTO BLOCKS VALUES(0,2147483647,0) diff --git a/wise-webapp/pom.xml b/wise-webapp/pom.xml index 7837066a..95de836d 100644 --- a/wise-webapp/pom.xml +++ b/wise-webapp/pom.xml @@ -146,7 +146,6 @@ 2.7.1 runtime - com.fasterxml.jackson.core jackson-databind @@ -198,101 +197,6 @@ compile - - - hsqldb - - true - - - - - org.codehaus.mojo - sql-maven-plugin - 1.5 - - - org.hsqldb.jdbc.JDBCDriver - jdbc:hsqldb:file:${project.build.directory}/db/wisemapping - sa - - - - - org.hsqldb - hsqldb - 2.7.2 - - - - - drop-schemas - prepare-package - - execute - - - continue - descending - - ${project.basedir} - - config/database/hsql/drop-schemas.sql - config/database/hsql/create-schemas.sql - config/database/hsql/apopulate-schemas.sql - - - - - - - - - - - mysqldb - - false - - - - - org.codehaus.mojo - sql-maven-plugin - 1.5 - - - mysql - mysql-connector-java - 8.0.31 - - - - - init-schema - - execute - - prepare-package - - - - com.mysql.jdbc.Driver - root - - jdbc:mysql://127.0.0.1:3306/?useUnicode=true&characterEncoding=UTF-8 - false - - config/database/mysql/create-database.sql - config/database/mysql/create-schemas.sql - config/database/mysql/apopulate-schemas.sql - - - - - - - diff --git a/wise-webapp/src/main/java/com/wisemapping/config/Application.java b/wise-webapp/src/main/java/com/wisemapping/config/Application.java index cb986831..daa5b5e1 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/Application.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/Application.java @@ -14,15 +14,15 @@ import org.springframework.security.web.firewall.StrictHttpFirewall; @SpringBootApplication @ImportResource(value = {"classpath:spring/wisemapping-service.xml"}) -@ComponentScan({"com.wisemapping.security", "com.wisemapping.service", "com.wisemapping.dao", "com.wisemapping.util"}) +@ComponentScan({"com.wisemapping.security", "com.wisemapping.service", "com.wisemapping.dao", "com.wisemapping.util", "com.wisemapping.model"}) public class Application { public static void main(String[] args) { new SpringApplicationBuilder() - .parent(Application.class, HibernateConfig.class, MethodSecurityConfig.class).web(WebApplicationType.NONE) - .child(MvcAppConfig.class, MvcSecurityConfig.class, ServletConfig.class).web(WebApplicationType.SERVLET) - .sibling(RestAppConfig.class).web(WebApplicationType.SERVLET) + .parent(Application.class, MethodSecurityConfig.class).web(WebApplicationType.NONE) + .child(MvcAppConfig.class, MvcSecurityConfig.class, HibernateConfig.class, ServletConfig.class).web(WebApplicationType.SERVLET) +// .sibling(RestAppConfig.class).web(WebApplicationType.SERVLET) .run(args); } diff --git a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java index 29bf47d1..94982292 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java @@ -8,37 +8,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @EnableTransactionManagement @EnableJpaRepositories("com.wisemapping.model") public class HibernateConfig { -// @Value("${database.hibernate.dialect}") -// private String dbDialect; -// -// @Value("${database.driver}") -// private String dbDriver; -// -// @Value("${database.url}") -// private String dbUrl; -// -// @Value("${database.username}") -// private String dbUsername; -// @Value("${database.password}") -// private String dbPassword; -// -// @Value("${database.validation.enabled:true}") -// private boolean dbSetOnBorrow; -// -// @Value("${database.validation.query:SELECT 1}") -// private String dbValQuery; -// @Bean -// public LocalSessionFactoryBean sessionFactory() { -// final LocalSessionFactoryBean result = new LocalSessionFactoryBean(); -// result.setPackagesToScan("com.wisemapping.model"); -// result.setDataSource(dataSource()); -// result.setHibernateProperties(hibernateProperties()); -// -// return result; -// } -// -// // @Bean // public HibernateTransactionManager hibernateTransactionManager() { // final HibernateTransactionManager result = new HibernateTransactionManager(); diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/LabelManagerImpl.java b/wise-webapp/src/main/java/com/wisemapping/dao/LabelManagerImpl.java index 92f39492..733831bc 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/LabelManagerImpl.java +++ b/wise-webapp/src/main/java/com/wisemapping/dao/LabelManagerImpl.java @@ -25,6 +25,7 @@ import org.hibernate.SessionFactory; import org.hibernate.query.SelectionQuery; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.List; @@ -32,7 +33,7 @@ import java.util.List; @Repository("labelManager") public class LabelManagerImpl implements LabelManager { - @Resource + @Autowired private SessionFactory sessionFactory; @Override diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java b/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java index 78c013b6..059f0e68 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java +++ b/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java @@ -22,6 +22,7 @@ import com.wisemapping.model.*; import com.wisemapping.security.DefaultPasswordEncoderFactories; import com.wisemapping.security.LegacyPasswordEncoder; import jakarta.annotation.Resource; +import jakarta.persistence.EntityManagerFactory; import org.hibernate.ObjectNotFoundException; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -39,8 +40,8 @@ import java.util.concurrent.CopyOnWriteArraySet; @Repository public class UserManagerImpl implements UserManager { -// @Autowired - private SessionFactory sessionFactory; + @Autowired + private EntityManagerFactory entityManagerFactory; @Autowired private PasswordEncoder passwordEncoder; @@ -54,7 +55,7 @@ public class UserManagerImpl } private Session getSession() { - return sessionFactory.getCurrentSession(); + return entityManagerFactory.unwrap(SessionFactory.class).getCurrentSession(); } diff --git a/wise-webapp/src/main/resources/application.properties b/wise-webapp/src/main/resources/application.properties index 6b3f60ee..96234d5f 100755 --- a/wise-webapp/src/main/resources/application.properties +++ b/wise-webapp/src/main/resources/application.properties @@ -1,37 +1,17 @@ ################################################################################## -# Database Configuration +Springboot Common ################################################################################## -# MySQL 5.X configuration properties -#database.url=jdbc:mysql://localhost/wisemapping?useUnicode=yes&characterEncoding=UTF-8 -#database.driver=com.mysql.cj.jdbc.Driver -#database.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect -#database.username=wisemapping -#database.password=password -#database.validation.enabled=true -#database.validation.query=SELECT 1 +spring.datasource.initialize=true +spring.jpa.open-in-view=true +#spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext +spring.sql.init.mode=always +spring.main.allow-circular-references=true -## PostgreSQL configuration properties -#database.url=jdbc:postgresql:///wisemapping -#database.driver=org.postgresql.Driver -#database.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect -#database.username=wisemapping -#database.password=password -#database.validation.enabled=true -#database.validation.query= -#database.validation.enabled=false +spring.jpa.properties.hibernate.current_session_context_class=thread +spring.jpa.properties.hibernate.format_sql=true - -##database.base.url=/Users/veigap/repos/wisemapping-open-source/wise-webapp -### HSQL Configuration properties -##database.url=jdbc:hsqldb:file:${database.base.url}/db/wisemapping -##database.driver=org.hsqldb.jdbc.JDBCDriver -##database.hibernate.dialect=org.hibernate.dialect.HSQLDialect -# -#database.username=sa -#database.password= -#database.validation.enabled=false -#database.validation.query= +logging.level.root=TRACE ################################################################################## # Mail configuration. Must be configured to enable user registration confirmation. @@ -155,8 +135,6 @@ security.oauth2.google.userinfoUrl=https://www.googleapis.com/oauth2/v3/userinfo security.oauth2.google.url=https//review - - ####################################################################################### # User Account filtering policies ####################################################################################### @@ -165,20 +143,13 @@ security.oauth2.google.url=https//review #accounts.exclusion.domain= -####################################################################################### -# Spring related configurations -####################################################################################### -spring.main.allow-circular-references=true +################################################################################## +# Database Configuration +################################################################################## -database.base.url=/Users/veigap/repos/wisemapping-open-source/wise-webapp +database.base.url=/Users/veigap/ spring.datasource.url=jdbc:hsqldb:file:${database.base.url}/db/wisemapping spring.datasource.username=sa spring.datasource.password= spring.datasource.driver-class-name = org.hsqldb.jdbc.JDBCDriver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect -spring.jpa.open-in-view=true -spring.h2.console.enabled=true -spring.h2.console.path=/h2-ui - - -logging.level.root=DEBUG diff --git a/config/database/hsql/apopulate-schemas.sql b/wise-webapp/src/main/resources/data-hsqldb.sql similarity index 100% rename from config/database/hsql/apopulate-schemas.sql rename to wise-webapp/src/main/resources/data-hsqldb.sql diff --git a/config/database/hsql/create-schemas.sql b/wise-webapp/src/main/resources/schema-hsqldb.sql similarity index 100% rename from config/database/hsql/create-schemas.sql rename to wise-webapp/src/main/resources/schema-hsqldb.sql From fbbc95fd59307b1149336d2db6588dd7d0f8abc7 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sat, 13 Jan 2024 18:31:21 -0800 Subject: [PATCH 007/110] Fix JPA load. --- .../java/com/wisemapping/config/Application.java | 9 ++++++--- .../com/wisemapping/config/HibernateConfig.java | 14 ++++++++++++-- .../java/com/wisemapping/dao/UserManagerImpl.java | 12 +++++++++--- .../src/main/resources/application.properties | 12 ++++++++---- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/wise-webapp/src/main/java/com/wisemapping/config/Application.java b/wise-webapp/src/main/java/com/wisemapping/config/Application.java index daa5b5e1..b30443e6 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/Application.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/Application.java @@ -20,10 +20,13 @@ public class Application { public static void main(String[] args) { new SpringApplicationBuilder() - .parent(Application.class, MethodSecurityConfig.class).web(WebApplicationType.NONE) - .child(MvcAppConfig.class, MvcSecurityConfig.class, HibernateConfig.class, ServletConfig.class).web(WebApplicationType.SERVLET) -// .sibling(RestAppConfig.class).web(WebApplicationType.SERVLET) + .parent(Application.class, MethodSecurityConfig.class, HibernateConfig.class).web(WebApplicationType.NONE) + .child(MvcAppConfig.class, MvcSecurityConfig.class, ServletConfig.class).web(WebApplicationType.SERVLET) + .sibling(RestAppConfig.class).web(WebApplicationType.SERVLET) .run(args); + +// new SpringApplicationBuilder(Application.class, MethodSecurityConfig.class,MvcAppConfig.class, MvcSecurityConfig.class, HibernateConfig.class, ServletConfig.class).web(WebApplicationType.SERVLET).run(args); + } @Bean diff --git a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java index 94982292..66ef9847 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java @@ -1,12 +1,22 @@ package com.wisemapping.config; +import com.wisemapping.model.User; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; +//@Configuration +//@EnableTransactionManagement +//@EnableJpaRepositories("com.wisemapping.model") + + @Configuration -@EnableTransactionManagement -@EnableJpaRepositories("com.wisemapping.model") +@EnableAutoConfiguration +@EnableJpaRepositories(basePackages={"com.wisemapping.dao"}) +@EntityScan(basePackageClasses= User.class) public class HibernateConfig { // @Bean diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java b/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java index 059f0e68..d66d2709 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java +++ b/wise-webapp/src/main/java/com/wisemapping/dao/UserManagerImpl.java @@ -21,8 +21,9 @@ package com.wisemapping.dao; import com.wisemapping.model.*; import com.wisemapping.security.DefaultPasswordEncoderFactories; import com.wisemapping.security.LegacyPasswordEncoder; -import jakarta.annotation.Resource; +import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.TypedQuery; import org.hibernate.ObjectNotFoundException; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -43,15 +44,20 @@ public class UserManagerImpl @Autowired private EntityManagerFactory entityManagerFactory; + @Autowired + private EntityManager entityManager; @Autowired private PasswordEncoder passwordEncoder; + public UserManagerImpl() { + } + public void setEncoder(PasswordEncoder passwordEncoder) { this.passwordEncoder = passwordEncoder; } public List getAllUsers() { - return getSession().createSelectionQuery("from com.wisemapping.model.User user", User.class).getResultList(); + return entityManager.createQuery("from com.wisemapping.model.User user", User.class).getResultList(); } private Session getSession() { @@ -64,7 +70,7 @@ public class UserManagerImpl public User getUserBy(@NotNull final String email) { User user = null; - SelectionQuery query = getSession().createSelectionQuery("from com.wisemapping.model.User colaborator where email=:email",User.class); + TypedQuery query = entityManager.createQuery("from com.wisemapping.model.User colaborator where email=:email",User.class); query.setParameter("email", email); final List users = query.getResultList(); diff --git a/wise-webapp/src/main/resources/application.properties b/wise-webapp/src/main/resources/application.properties index 96234d5f..27d1f01d 100755 --- a/wise-webapp/src/main/resources/application.properties +++ b/wise-webapp/src/main/resources/application.properties @@ -3,15 +3,19 @@ Springboot Common ################################################################################## spring.datasource.initialize=true -spring.jpa.open-in-view=true -#spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext -spring.sql.init.mode=always spring.main.allow-circular-references=true +spring.jpa.open-in-view=true spring.jpa.properties.hibernate.current_session_context_class=thread spring.jpa.properties.hibernate.format_sql=true +spring.sql.init.mode=always -logging.level.root=TRACE +################################################################################## +Log Level +################################################################################## + +logging.level.root=INFO +logging.level.org.apache.tomcat=INFO ################################################################################## # Mail configuration. Must be configured to enable user registration confirmation. From 2f32ef66e9742c23f37df65b096c178879664db3 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sat, 13 Jan 2024 18:49:49 -0800 Subject: [PATCH 008/110] Migrate all to entity manager. --- .../wisemapping/config/HibernateConfig.java | 6 -- .../com/wisemapping/dao/LabelManagerImpl.java | 27 +++----- .../wisemapping/dao/MindmapManagerImpl.java | 62 +++++++------------ .../com/wisemapping/dao/UserManagerImpl.java | 44 ++++--------- 4 files changed, 44 insertions(+), 95 deletions(-) diff --git a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java index 66ef9847..b5d266b7 100644 --- a/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java +++ b/wise-webapp/src/main/java/com/wisemapping/config/HibernateConfig.java @@ -3,14 +3,8 @@ package com.wisemapping.config; import com.wisemapping.model.User; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -//@Configuration -//@EnableTransactionManagement -//@EnableJpaRepositories("com.wisemapping.model") @Configuration diff --git a/wise-webapp/src/main/java/com/wisemapping/dao/LabelManagerImpl.java b/wise-webapp/src/main/java/com/wisemapping/dao/LabelManagerImpl.java index 733831bc..dd6d7472 100644 --- a/wise-webapp/src/main/java/com/wisemapping/dao/LabelManagerImpl.java +++ b/wise-webapp/src/main/java/com/wisemapping/dao/LabelManagerImpl.java @@ -19,10 +19,8 @@ package com.wisemapping.dao; import com.wisemapping.model.Label; import com.wisemapping.model.User; -import jakarta.annotation.Resource; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.query.SelectionQuery; +import jakarta.persistence.EntityManager; +import jakarta.persistence.TypedQuery; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; @@ -34,7 +32,7 @@ import java.util.List; public class LabelManagerImpl implements LabelManager { @Autowired - private SessionFactory sessionFactory; + private EntityManager entityManager; @Override public void addLabel(@NotNull final Label label) { @@ -43,26 +41,21 @@ public class LabelManagerImpl @Override public void saveLabel(@NotNull final Label label) { - getSession().persist(label); - } - - private Session getSession() { - return sessionFactory.getCurrentSession(); + entityManager.persist(label); } @NotNull @Override public List - - org.apache.maven.plugins - maven-war-plugin - 3.4.0 - - false - - - target - - wisemapping-*/**/dist/* - - - - diff --git a/wise-webapp/config b/wise-webapp/config deleted file mode 120000 index 40885268..00000000 --- a/wise-webapp/config +++ /dev/null @@ -1 +0,0 @@ -../config/ \ No newline at end of file diff --git a/wise-webapp/webdefault.xml b/wise-webapp/webdefault.xml deleted file mode 100644 index 9cecd06d..00000000 --- a/wise-webapp/webdefault.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - default - org.eclipse.jetty.servlet.DefaultServlet - - aliases - true - - - \ No newline at end of file From 01e0639c5502ca8d9594eb64fcf4c1da2df023fd Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sat, 3 Feb 2024 23:22:38 -0800 Subject: [PATCH 048/110] Fix compose. --- docker-compose.yaml => docker-compose.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename docker-compose.yaml => docker-compose.yml (56%) diff --git a/docker-compose.yaml b/docker-compose.yml similarity index 56% rename from docker-compose.yaml rename to docker-compose.yml index 3ceb14ea..e15b74e7 100644 --- a/docker-compose.yaml +++ b/docker-compose.yml @@ -6,10 +6,10 @@ services: dockerfile: Dockerfile ports: - "8080:8080" - environment: - SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/product - SPRING_DATASOURCE_USERNAME: product_user - SPRING_DATASOURCE_PASSWORD: product_user_password +# environment: +# SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/product +# SPRING_DATASOURCE_USERNAME: product_user +# SPRING_DATASOURCE_PASSWORD: product_user_password react-app: build: @@ -18,4 +18,4 @@ services: depends_on: - wise-api ports: - - "3000:80" \ No newline at end of file + - "80:80" \ No newline at end of file From b3ea3e5a5b7c5ab1a97fc3ee4de6269bf79c7a21 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 08:45:00 -0800 Subject: [PATCH 049/110] Container load. --- docker-compose.yml | 12 ++++++------ wise-ui/Dockerfile | 7 +++++-- wise-ui/nginx.conf | 27 +++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 wise-ui/nginx.conf diff --git a/docker-compose.yml b/docker-compose.yml index e15b74e7..d824f268 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,17 @@ version: '3' + services: wise-api: + container_name: wise-api + image: wise-api:latest build: context: ./wise-api dockerfile: Dockerfile ports: - "8080:8080" -# environment: -# SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/product -# SPRING_DATASOURCE_USERNAME: product_user -# SPRING_DATASOURCE_PASSWORD: product_user_password - - react-app: + wise-ui: + container_name: wise-ui + image: wise-ui:latest build: context: ./wise-ui dockerfile: Dockerfile diff --git a/wise-ui/Dockerfile b/wise-ui/Dockerfile index f5a432a5..df3f72e2 100644 --- a/wise-ui/Dockerfile +++ b/wise-ui/Dockerfile @@ -11,14 +11,17 @@ RUN mkdir mindplot && npm pack @wisemapping/mindplot@${VERSION} && tar -xvzf wis ADD index.html . # Use Nginx as the production server -FROM nginx:stable-alpine +FROM nginx:latest LABEL maintainer="Paulo Gustavo Veiga " ## Copy the built React app to Nginx's web server directory -COPY --from=builder /app /usr/share/nginx/html +COPY --from=builder /app/index.html /usr/share/nginx/html/ COPY --from=builder /app/webapp/package/dist/* /usr/share/nginx/html/webapp/ COPY --from=builder /app/mindplot/package/dist/* /usr/share/nginx/html/mindplot/ +ADD nginx.conf . +COPY nginx.conf /etc/nginx/conf.d/default.conf + # Expose port 80 for the Nginx server EXPOSE 80 diff --git a/wise-ui/nginx.conf b/wise-ui/nginx.conf new file mode 100644 index 00000000..75d549c6 --- /dev/null +++ b/wise-ui/nginx.conf @@ -0,0 +1,27 @@ +server { + listen 80; + gzip on; + charset UTF-8; + server_name wise-ui; + + location / { + # This would be the directory where your React app's static files are stored at + root /usr/share/nginx/html; + try_files $uri /index.html; + } + + location /c/ { + try_files $uri /usr/share/nginx/html/index.html; + } + + location /api/ { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-NginX-Proxy true; + proxy_pass http://localhost:8080/api/; + proxy_ssl_session_reuse off; + proxy_set_header Host $http_host; + proxy_cache_bypass $http_upgrade; + proxy_redirect off; + } +} From d4c50b4c2a6a025c10bb7cc9a6cdcbfdd757c5c2 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 08:54:07 -0800 Subject: [PATCH 050/110] Remove MVC ui support. --- pom.xml | 154 ----------------------------------------------- wise-api/pom.xml | 53 +++++++--------- 2 files changed, 22 insertions(+), 185 deletions(-) delete mode 100644 pom.xml diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 286e4f10..00000000 --- a/pom.xml +++ /dev/null @@ -1,154 +0,0 @@ - - - - 5.1.0-SNAPSHOT - ${project.basedir}/wise-webapps - 17 - 17 - - - - scm:git:git@bitbucket.org:wisemapping/wisemapping-open-source.git - - - 4.0.0 - org.wisemapping - wisemapping - WiseMapping Project - 5.1.0-SNAPSHOT - pom - - - - WiseMapping Public License Version 1.0 - http://www.wisemapping.org/wisemapping-public-license-version-1-0-wpl - A business-friendly OSS license - - - - - - maven2-repository.dev.java.net - Java.net Maven 2 Repository - http://download.java.net/maven/2/ - default - - - - - WiseMapping - http://www.wisemapping.org/ - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.11.0 - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.12 - - - exec-maven-plugin - org.codehaus.mojo - 3.0.0 - - - org.apache.maven.plugins - maven-resources-plugin - 3.3.1 - - - org.apache.maven.plugins - maven-site-plugin - 3.1 - - - org.apache.maven.plugins - maven-project-info-reports-plugin - 2.4 - - - org.apache.maven.plugins - maven-dependency-plugin - 2.10 - - - net.alchim31.maven - yuicompressor-maven-plugin - 1.1 - - - org.apache.maven.plugins - maven-antrun-plugin - 1.7 - - - org.codehaus.mojo - native2ascii-maven-plugin - 1.0-beta-1 - - - com.github.searls - jasmine-maven-plugin - 1.3.1.5 - - - org.apache.maven.plugins - maven-release-plugin - 2.5 - - - - - - org.apache.maven.plugins - maven-resources-plugin - - UTF-8 - - - - org.apache.maven.plugins - maven-compiler-plugin - - UTF-8 - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.2.2 - - - distribution/assembly/standalone-editor.xml - - - - - - - - - www.wisemapping.org - scp://www.wisemapping.org/docs/project/ - - - - - - wise-ui - wise-webapp - - - - - diff --git a/wise-api/pom.xml b/wise-api/pom.xml index c3785424..e3a3a406 100644 --- a/wise-api/pom.xml +++ b/wise-api/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent 3.2.1 - + org.wisemapping @@ -19,18 +19,9 @@ 5.1.0-SNAPSHOT 17 17 - 6.0.11 - 6.1.2 - 6.0.2 - - org.wisemapping - wise-ui - ${com.wisemapping.version} - war - org.apache.velocity velocity @@ -63,6 +54,7 @@ 6.1.3 test + org.junit.jupiter junit-jupiter-api @@ -104,11 +96,6 @@ postgresql 42.5.4 - - org.springframework.security - spring-security-taglibs - ${spring-security-taglibs.version} - jakarta.xml.bind jakarta.xml.bind-api @@ -180,38 +167,42 @@ 6.0.0 provided - - - jakarta.servlet.jsp.jstl - jakarta.servlet.jsp.jstl-api - 3.0.0 - - - org.glassfish.web - jakarta.servlet.jsp.jstl - 3.0.0 - + commons-io commons-io 2.11.0 + org.apache.httpcomponents fluent-hc 4.5.14 - - org.springframework.security - spring-security-config - ${org.springframework.addons} - + org.projectlombok lombok RELEASE compile + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + From fdffda61864dbee606ea670f3badc7cc6dcb56ca Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 10:09:10 -0800 Subject: [PATCH 051/110] Improve code. --- wise-api/pom.xml | 29 +++++++++---------- .../wisemapping/rest/AccountController.java | 13 +++++---- .../com/wisemapping/rest/AdminController.java | 11 +++---- .../wisemapping/rest/MindmapController.java | 2 +- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/wise-api/pom.xml b/wise-api/pom.xml index e3a3a406..549f5e29 100644 --- a/wise-api/pom.xml +++ b/wise-api/pom.xml @@ -5,7 +5,6 @@ org.springframework.boot spring-boot-starter-parent 3.2.1 - org.wisemapping @@ -85,12 +84,6 @@ 12.0 compile - - org.apache.tomcat.embed - tomcat-embed-jasper - 10.1.9 - provided - org.postgresql postgresql @@ -149,6 +142,7 @@ 2.7.1 runtime + com.fasterxml.jackson.core jackson-databind @@ -161,13 +155,6 @@ 2.0.1 - - jakarta.servlet - jakarta.servlet-api - 6.0.0 - provided - - commons-io commons-io @@ -183,10 +170,11 @@ org.projectlombok lombok - RELEASE + 1.18.26 compile + io.jsonwebtoken jjwt-api @@ -197,7 +185,6 @@ jjwt-impl 0.11.5 - io.jsonwebtoken jjwt-jackson @@ -233,4 +220,14 @@ + + + spring-snapshots + https://repo.spring.io/snapshot + + + spring-milestones + https://repo.spring.io/milestone + + \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/rest/AccountController.java b/wise-api/src/main/java/com/wisemapping/rest/AccountController.java index c82d1372..52a870dc 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/AccountController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/AccountController.java @@ -39,6 +39,7 @@ import org.springframework.web.bind.annotation.*; import java.util.List; @RestController +@RequestMapping("/api/restfull/account/") @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") public class AccountController extends BaseController { @Qualifier("userService") @@ -53,7 +54,7 @@ public class AccountController extends BaseController { @Autowired private LabelService labelService; - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/account/password", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "password", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changePassword(@RequestBody String password) throws PasswordTooLongException { if (password == null) { @@ -69,13 +70,13 @@ public class AccountController extends BaseController { userService.changePassword(user); } - @RequestMapping(method = RequestMethod.GET, value = "/api/restfull/account", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "", produces = {"application/json"}) public RestUser fetchAccount() { final User user = Utils.getUser(true); return new RestUser(user); } - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/account/firstname", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "firstname", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changeFirstname(@RequestBody String firstname) { if (firstname == null) { @@ -87,7 +88,7 @@ public class AccountController extends BaseController { userService.updateUser(user); } - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/account/lastname", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "lastname", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changeLastName(@RequestBody String lastname) { if (lastname == null) { @@ -99,7 +100,7 @@ public class AccountController extends BaseController { userService.updateUser(user); } - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/account/locale", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "locale", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changeLanguage(@RequestBody String language) { if (language == null) { @@ -113,7 +114,7 @@ public class AccountController extends BaseController { } @ResponseStatus(value = HttpStatus.NO_CONTENT) - @RequestMapping(method = RequestMethod.DELETE, value = "/api/restfull/account") + @RequestMapping(method = RequestMethod.DELETE, value = "") public void deleteUser() throws WiseMappingException { // Delete collaborations ... final User user = Utils.getUser(true); diff --git a/wise-api/src/main/java/com/wisemapping/rest/AdminController.java b/wise-api/src/main/java/com/wisemapping/rest/AdminController.java index cd199ad5..ec2638d5 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/AdminController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/AdminController.java @@ -37,6 +37,7 @@ import java.io.IOException; import java.util.List; @RestController +@RequestMapping("/api/restfull/admin/") @PreAuthorize("isAuthenticated() and hasRole('ROLE_ADMIN')") public class AdminController extends BaseController { @Qualifier("userService") @@ -47,7 +48,7 @@ public class AdminController extends BaseController { @Autowired private MindmapService mindmapService; - @RequestMapping(method = RequestMethod.GET, value = "/api/restfull/admin/users/{id}", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "users/{id}", produces = {"application/json"}) @ResponseBody public RestUser getUserById(@PathVariable int id) throws IOException { final User userBy = userService.getUserBy(id); @@ -57,7 +58,7 @@ public class AdminController extends BaseController { return new RestUser(userBy); } - @RequestMapping(method = RequestMethod.GET, value = "/api/restfull/admin/users/email/{email:.+}", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "users/email/{email:.+}", produces = {"application/json"}) @ResponseBody public RestUser getUserByEmail(@PathVariable String email) throws IOException { final User user = userService.getUserBy(email); @@ -67,7 +68,7 @@ public class AdminController extends BaseController { return new RestUser(user); } - @RequestMapping(method = RequestMethod.POST, value = "/api/restfull/admin/users", consumes = {"application/json"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.POST, value = "users", consumes = {"application/json"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.CREATED) public void createUser(@RequestBody RestUser user, HttpServletResponse response) throws WiseMappingException { if (user == null) { @@ -104,7 +105,7 @@ public class AdminController extends BaseController { response.setHeader("Location", "/api/restfull/admin/users/" + user.getId()); } - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/admin/users/{id}/password", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "users/{id}/password", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changePassword(@RequestBody String password, @PathVariable int id) throws WiseMappingException { if (password == null) { @@ -119,7 +120,7 @@ public class AdminController extends BaseController { userService.changePassword(user); } - @RequestMapping(method = RequestMethod.DELETE, value = "/api/restfull/admin/users/{id}") + @RequestMapping(method = RequestMethod.DELETE, value = "users/{id}") @ResponseStatus(value = HttpStatus.NO_CONTENT) public void deleteUserByEmail(@PathVariable int id) throws WiseMappingException { final User user = userService.getUserBy(id); diff --git a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java index a8ea9da2..3bf17a74 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java @@ -48,7 +48,7 @@ import java.util.stream.Collectors; @RestController -@Transactional(propagation = Propagation.REQUIRED) +//@RequestMapping("/api/restfull/labels") public class MindmapController extends BaseController { private final Logger logger = LogManager.getLogger(); From af4016cadd7fdc0b9f37582045b3c95925635457 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 10:42:16 -0800 Subject: [PATCH 052/110] Improve code on rest. --- .../com/wisemapping/rest/AdminController.java | 20 +++--- .../com/wisemapping/rest/LabelController.java | 10 +-- .../wisemapping/rest/MindmapController.java | 66 +++++++++---------- .../com/wisemapping/rest/UserController.java | 7 +- .../com/wisemapping/rest/model/RestLabel.java | 18 +++++ .../src/main/resources/public/static/mindplot | 1 - .../src/main/resources/public/static/webapp | 1 - 7 files changed, 68 insertions(+), 55 deletions(-) delete mode 120000 wise-api/src/main/resources/public/static/mindplot delete mode 120000 wise-api/src/main/resources/public/static/webapp diff --git a/wise-api/src/main/java/com/wisemapping/rest/AdminController.java b/wise-api/src/main/java/com/wisemapping/rest/AdminController.java index ec2638d5..10dd3a2b 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/AdminController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/AdminController.java @@ -33,11 +33,10 @@ import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import java.io.IOException; import java.util.List; @RestController -@RequestMapping("/api/restfull/admin/") +@RequestMapping("/api/restfull/admin") @PreAuthorize("isAuthenticated() and hasRole('ROLE_ADMIN')") public class AdminController extends BaseController { @Qualifier("userService") @@ -48,9 +47,9 @@ public class AdminController extends BaseController { @Autowired private MindmapService mindmapService; - @RequestMapping(method = RequestMethod.GET, value = "users/{id}", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "/users/{id}", produces = {"application/json"}) @ResponseBody - public RestUser getUserById(@PathVariable int id) throws IOException { + public RestUser getUserById(@PathVariable int id) { final User userBy = userService.getUserBy(id); if (userBy == null) { throw new IllegalArgumentException("User could not be found"); @@ -58,9 +57,9 @@ public class AdminController extends BaseController { return new RestUser(userBy); } - @RequestMapping(method = RequestMethod.GET, value = "users/email/{email:.+}", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "/users/email/{email:.+}", produces = {"application/json"}) @ResponseBody - public RestUser getUserByEmail(@PathVariable String email) throws IOException { + public RestUser getUserByEmail(@PathVariable String email) { final User user = userService.getUserBy(email); if (user == null) { throw new IllegalArgumentException("User '" + email + "' could not be found"); @@ -68,7 +67,7 @@ public class AdminController extends BaseController { return new RestUser(user); } - @RequestMapping(method = RequestMethod.POST, value = "users", consumes = {"application/json"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.POST, value = "/users", consumes = {"application/json"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.CREATED) public void createUser(@RequestBody RestUser user, HttpServletResponse response) throws WiseMappingException { if (user == null) { @@ -105,9 +104,9 @@ public class AdminController extends BaseController { response.setHeader("Location", "/api/restfull/admin/users/" + user.getId()); } - @RequestMapping(method = RequestMethod.PUT, value = "users/{id}/password", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "/users/{id}/password", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) - public void changePassword(@RequestBody String password, @PathVariable int id) throws WiseMappingException { + public void changePassword(@RequestBody String password, @PathVariable int id) { if (password == null) { throw new IllegalArgumentException("Password can not be null"); } @@ -120,7 +119,7 @@ public class AdminController extends BaseController { userService.changePassword(user); } - @RequestMapping(method = RequestMethod.DELETE, value = "users/{id}") + @RequestMapping(method = RequestMethod.DELETE, value = "/users/{id}") @ResponseStatus(value = HttpStatus.NO_CONTENT) public void deleteUserByEmail(@PathVariable int id) throws WiseMappingException { final User user = userService.getUserBy(id); @@ -133,7 +132,6 @@ public class AdminController extends BaseController { final Mindmap mindmap = collaboration.getMindMap(); mindmapService.removeMindmap(mindmap, user); } - userService.removeUser(user); } } diff --git a/wise-api/src/main/java/com/wisemapping/rest/LabelController.java b/wise-api/src/main/java/com/wisemapping/rest/LabelController.java index e99c806e..694524f4 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/LabelController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/LabelController.java @@ -27,20 +27,20 @@ import com.wisemapping.rest.model.RestLabelList; import com.wisemapping.security.Utils; import com.wisemapping.service.LabelService; import com.wisemapping.validator.LabelValidator; +import jakarta.servlet.http.HttpServletResponse; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; -import jakarta.servlet.http.HttpServletResponse; import java.util.List; @RestController +@RequestMapping("/api/restfull/labels") @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") public class LabelController extends BaseController { @@ -49,7 +49,7 @@ public class LabelController extends BaseController { private LabelService labelService; - @RequestMapping(method = RequestMethod.POST, value = "/api/restfull/labels", consumes = {"application/json"}) + @RequestMapping(method = RequestMethod.POST, value = "", consumes = {"application/json"}) @ResponseStatus(value = HttpStatus.CREATED) public void createLabel(@RequestBody RestLabel restLabel, @NotNull HttpServletResponse response, @RequestParam(required = false) String title) throws WiseMappingException { // Overwrite title if it was specified by parameter. @@ -67,7 +67,7 @@ public class LabelController extends BaseController { response.setHeader("ResourceId", Long.toString(label.getId())); } - @RequestMapping(method = RequestMethod.GET, value = "/api/restfull/labels/", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "/", produces = {"application/json"}) public RestLabelList retrieveList() { final User user = Utils.getUser(); assert user != null; @@ -75,7 +75,7 @@ public class LabelController extends BaseController { return new RestLabelList(all); } - @RequestMapping(method = RequestMethod.DELETE, value = "/api/restfull/labels/{id}") + @RequestMapping(method = RequestMethod.DELETE, value = "/{id}") @ResponseStatus(value = HttpStatus.NO_CONTENT) public void deleteLabelById(@PathVariable int id) throws WiseMappingException { final User user = Utils.getUser(); diff --git a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java index 3bf17a74..13850c9c 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java @@ -35,8 +35,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; @@ -48,7 +46,7 @@ import java.util.stream.Collectors; @RestController -//@RequestMapping("/api/restfull/labels") +@RequestMapping("/api/restfull/maps") public class MindmapController extends BaseController { private final Logger logger = LogManager.getLogger(); @@ -71,7 +69,7 @@ public class MindmapController extends BaseController { @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.GET, value = "/api/restfull/maps/{id}", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = {"application/json"}) @ResponseBody public RestMindmap retrieve(@PathVariable int id) throws WiseMappingException { final User user = Utils.getUser(); @@ -80,7 +78,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.GET, value = "/api/restfull/maps/", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "/", produces = {"application/json"}) public RestMindmapList retrieveList(@RequestParam(required = false) String q) { final User user = Utils.getUser(); @@ -94,7 +92,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.GET, value = "/api/restfull/maps/{id}/history/", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "/{id}/history/", produces = {"application/json"}) public RestMindmapHistoryList fetchHistory(@PathVariable int id) { final List histories = mindmapService.findMindmapHistory(id); final RestMindmapHistoryList result = new RestMindmapHistoryList(); @@ -104,7 +102,7 @@ public class MindmapController extends BaseController { return result; } - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/maps/{id}/document", consumes = {"application/json"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.PUT, value = "/{id}/document", consumes = {"application/json"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") @@ -136,7 +134,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(value = "/api/restfull/maps/{id}/history/{hid}", method = RequestMethod.POST) + @RequestMapping(value = "/{id}/history/{hid}", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void updateRevertMindmap(@PathVariable int id, @PathVariable String hid) throws WiseMappingException, IOException { final Mindmap mindmap = findMindmapById(id); @@ -156,7 +154,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("permitAll()") - @RequestMapping(method = RequestMethod.GET, value = {"/api/restfull/maps/{id}/document/xml", "/api/restfull/maps/{id}/document/xml-pub"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"}) + @RequestMapping(method = RequestMethod.GET, value = {"/{id}/document/xml", "/{id}/document/xml-pub"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"}) @ResponseBody public byte[] retrieveDocument(@PathVariable int id, @NotNull HttpServletResponse response) throws WiseMappingException, IOException { final Mindmap mindmap = findMindmapById(id); @@ -166,9 +164,9 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.PUT, value = {"/api/restfull/maps/{id}/document/xml"}, consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = {"/{id}/document/xml"}, consumes = {"text/plain"}) @ResponseBody - public void updateDocument(@PathVariable int id, @RequestBody String xmlDoc) throws WiseMappingException, IOException { + public void updateDocument(@PathVariable int id, @RequestBody String xmlDoc) throws WiseMappingException { final Mindmap mindmap = findMindmapById(id); final User user = Utils.getUser(); mindmap.setXmlStr(xmlDoc); @@ -178,7 +176,7 @@ public class MindmapController extends BaseController { @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.GET, value = {"/api/restfull/maps/{id}/{hid}/document/xml"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"}) + @RequestMapping(method = RequestMethod.GET, value = {"/{id}/{hid}/document/xml"}, consumes = {"text/plain"}, produces = {"application/xml; charset=UTF-8"}) @ResponseBody public byte[] retrieveDocument(@PathVariable int id, @PathVariable int hid, @NotNull HttpServletResponse response) throws WiseMappingException, IOException { final MindMapHistory mindmapHistory = mindmapService.findMindmapHistory(id, hid); @@ -190,7 +188,7 @@ public class MindmapController extends BaseController { * The intention of this method is the update of several properties at once ... */ @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/maps/{id}", consumes = {"application/json"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.PUT, value = "/{id}", consumes = {"application/json"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void updateProperties(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws IOException, WiseMappingException { @@ -245,7 +243,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/maps/{id}/title", consumes = {"text/plain"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.PUT, value = "/{id}/title", consumes = {"text/plain"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void updateTitle(@RequestBody String title, @PathVariable int id) throws WiseMappingException { @@ -264,7 +262,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.POST, value = "/api/restfull/maps/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.POST, value = "/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void updateCollabs(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException, MapCouldNotFoundException, AccessDeniedSecurityException, InvalidEmailException, TooManyInactiveAccountsExceptions { final Mindmap mindMap = findMindmapById(id); @@ -314,7 +312,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/maps/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.PUT, value = "/{id}/collabs/", consumes = {"application/json"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void addCollab(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException, MapCouldNotFoundException, AccessDeniedSecurityException, InvalidEmailException, TooManyInactiveAccountsExceptions, OwnerCannotChangeException { final Mindmap mindMap = findMindmapById(id); @@ -382,7 +380,7 @@ public class MindmapController extends BaseController { @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.GET, value = "/api/restfull/maps/{id}/collabs", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "/{id}/collabs", produces = {"application/json"}) public RestCollaborationList retrieveList(@PathVariable int id) throws MapCouldNotFoundException, AccessDeniedSecurityException { final Mindmap mindMap = findMindmapById(id); @@ -399,7 +397,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/maps/{id}/description", consumes = {"text/plain"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.PUT, value = "/{id}/description", consumes = {"text/plain"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void updateDescription(@RequestBody String description, @PathVariable int id) throws WiseMappingException { final Mindmap mindmap = findMindmapById(id); @@ -408,7 +406,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/maps/{id}/publish", consumes = {"text/plain"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.PUT, value = "/{id}/publish", consumes = {"text/plain"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void updatePublishState(@RequestBody String value, @PathVariable int id) throws WiseMappingException { @@ -426,18 +424,18 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.DELETE, value = "/api/restfull/maps/{id}") + @RequestMapping(method = RequestMethod.DELETE, value = "/{id}") @ResponseStatus(value = HttpStatus.NO_CONTENT) - public void deleteMapById(@PathVariable int id) throws IOException, WiseMappingException { + public void deleteMapById(@PathVariable int id) throws WiseMappingException { final User user = Utils.getUser(); final Mindmap mindmap = findMindmapById(id); mindmapService.removeMindmap(mindmap, user); } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.DELETE, value = "/api/restfull/maps/{id}/collabs") + @RequestMapping(method = RequestMethod.DELETE, value = "/{id}/collabs") @ResponseStatus(value = HttpStatus.NO_CONTENT) - public void deleteCollabByEmail(@PathVariable int id, @RequestParam(required = false) String email) throws IOException, WiseMappingException { + public void deleteCollabByEmail(@PathVariable int id, @RequestParam(required = false) String email) throws WiseMappingException { logger.debug("Deleting permission for email:" + email); // Is a valid email address ? @@ -467,7 +465,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/maps/{id}/starred", consumes = {"text/plain"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.PUT, value = "/{id}/starred", consumes = {"text/plain"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void updateStarredState(@RequestBody String value, @PathVariable int id) throws WiseMappingException { @@ -486,7 +484,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.GET, value = "/api/restfull/maps/{id}/starred", produces = {"text/plain"}) + @RequestMapping(method = RequestMethod.GET, value = "/{id}/starred", produces = {"text/plain"}) @ResponseBody public String fetchStarred(@PathVariable int id) throws WiseMappingException { final Mindmap mindmap = findMindmapById(id); @@ -501,9 +499,9 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.DELETE, value = "/api/restfull/maps/batch") + @RequestMapping(method = RequestMethod.DELETE, value = "/batch") @ResponseStatus(value = HttpStatus.NO_CONTENT) - public void batchDelete(@RequestParam() String ids) throws IOException, WiseMappingException { + public void batchDelete(@RequestParam() String ids) throws WiseMappingException { final User user = Utils.getUser(); final String[] mapsIds = ids.split(","); try { @@ -519,9 +517,9 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.POST, value = "/api/restfull/maps", consumes = {"application/xml", "application/json"}) + @RequestMapping(method = RequestMethod.POST, value = "", consumes = {"application/xml", "application/json"}) @ResponseStatus(value = HttpStatus.CREATED) - public void createMap(@RequestBody(required = false) String mapXml, @NotNull HttpServletResponse response, @RequestParam(required = false) String title, @RequestParam(required = false) String description) throws IOException, WiseMappingException { + public void createMap(@RequestBody(required = false) String mapXml, @NotNull HttpServletResponse response, @RequestParam(required = false) String title, @RequestParam(required = false) String description) throws WiseMappingException { final Mindmap mindmap = new Mindmap(); if (title != null && !title.isEmpty()) { @@ -555,9 +553,9 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.POST, value = "/api/restfull/maps/{id}", consumes = {"application/json"}, produces = {"application/json", "text/plain"}) + @RequestMapping(method = RequestMethod.POST, value = "/{id}", consumes = {"application/json"}, produces = {"application/json", "text/plain"}) @ResponseStatus(value = HttpStatus.CREATED) - public void createDuplicate(@RequestBody RestMindmapInfo restMindmap, @PathVariable int id, @NotNull HttpServletResponse response) throws IOException, WiseMappingException { + public void createDuplicate(@RequestBody RestMindmapInfo restMindmap, @PathVariable int id, @NotNull HttpServletResponse response) throws WiseMappingException { // Validate ... final BindingResult result = new BeanPropertyBindingResult(restMindmap, ""); new MapInfoValidator(mindmapService).validate(restMindmap.getDelegated(), result); @@ -584,7 +582,7 @@ public class MindmapController extends BaseController { @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.DELETE, value = "/api/restfull/maps/{id}/labels/{lid}") + @RequestMapping(method = RequestMethod.DELETE, value = "/{id}/labels/{lid}") @ResponseStatus(value = HttpStatus.NO_CONTENT) public void removeLabelFromMap(@PathVariable int id, @PathVariable int lid) throws WiseMappingException { final User user = Utils.getUser(); @@ -600,7 +598,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.POST, value = "/api/restfull/maps/{id}/labels", consumes = {"application/json"}) + @RequestMapping(method = RequestMethod.POST, value = "/{id}/labels", consumes = {"application/json"}) @ResponseStatus(value = HttpStatus.OK) public void updateLabel(@PathVariable int id, @RequestBody int lid) throws WiseMappingException { final User user = Utils.getUser(); @@ -615,7 +613,7 @@ public class MindmapController extends BaseController { } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.PUT, value = "/api/restfull/maps/{id}/lock", consumes = {"text/plain"}, produces = {"application/json"}) + @RequestMapping(method = RequestMethod.PUT, value = "/{id}/lock", consumes = {"text/plain"}, produces = {"application/json"}) public ResponseEntity lockMindmap(@RequestBody String value, @PathVariable int id) throws WiseMappingException { final User user = Utils.getUser(); final LockManager lockManager = mindmapService.getLockManager(); diff --git a/wise-api/src/main/java/com/wisemapping/rest/UserController.java b/wise-api/src/main/java/com/wisemapping/rest/UserController.java index 6208e365..b10b8ed0 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/UserController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/UserController.java @@ -48,6 +48,7 @@ import java.util.Arrays; import java.util.List; @RestController +@RequestMapping("/api/restfull/users") @CrossOrigin public class UserController extends BaseController { @@ -71,7 +72,7 @@ public class UserController extends BaseController { private static final Logger logger = LogManager.getLogger(); private static final String REAL_IP_ADDRESS_HEADER = "X-Real-IP"; - @RequestMapping(method = RequestMethod.POST, value = "/users/", produces = { "application/json" }) + @RequestMapping(method = RequestMethod.POST, value = "/", produces = { "application/json" }) @ResponseStatus(value = HttpStatus.CREATED) public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws WiseMappingException, BindException { @@ -98,10 +99,10 @@ public class UserController extends BaseController { user.setAuthenticationType(AuthenticationType.DATABASE); userService.createUser(user, false, true); - response.setHeader("Location", "/service/users/" + user.getId()); + response.setHeader("Location", "/api/restfull/users/" + user.getId()); } - @RequestMapping(method = RequestMethod.PUT, value = "/users/resetPassword", produces = { "application/json" }) + @RequestMapping(method = RequestMethod.PUT, value = "/resetPassword", produces = { "application/json" }) @ResponseStatus(value = HttpStatus.OK) public RestResetPasswordResponse resetPassword(@RequestParam String email) throws InvalidAuthSchemaException, EmailNotExistsException { try { diff --git a/wise-api/src/main/java/com/wisemapping/rest/model/RestLabel.java b/wise-api/src/main/java/com/wisemapping/rest/model/RestLabel.java index 5a49fd38..24086818 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/model/RestLabel.java +++ b/wise-api/src/main/java/com/wisemapping/rest/model/RestLabel.java @@ -1,3 +1,21 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.wisemapping.rest.model; import com.fasterxml.jackson.annotation.JsonAutoDetect; diff --git a/wise-api/src/main/resources/public/static/mindplot b/wise-api/src/main/resources/public/static/mindplot deleted file mode 120000 index 61ad9a4e..00000000 --- a/wise-api/src/main/resources/public/static/mindplot +++ /dev/null @@ -1 +0,0 @@ -../../../../../../wise-ui/target/wisemapping-mindplot/package/dist \ No newline at end of file diff --git a/wise-api/src/main/resources/public/static/webapp b/wise-api/src/main/resources/public/static/webapp deleted file mode 120000 index 240a1953..00000000 --- a/wise-api/src/main/resources/public/static/webapp +++ /dev/null @@ -1 +0,0 @@ -../../../../../../wise-ui/target/wisemapping-webapp/package/dist \ No newline at end of file From 9382fc2995f075451183c3cb0d2f0b0cfa78a52e Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 10:47:10 -0800 Subject: [PATCH 053/110] Clean up code. --- wise-api/src/main/resources/spring.tld | 399 ------------------ .../resources/spring/wisemapping-rest.xml | 61 --- 2 files changed, 460 deletions(-) delete mode 100644 wise-api/src/main/resources/spring.tld delete mode 100644 wise-api/src/main/resources/spring/wisemapping-rest.xml diff --git a/wise-api/src/main/resources/spring.tld b/wise-api/src/main/resources/spring.tld deleted file mode 100644 index 40681a11..00000000 --- a/wise-api/src/main/resources/spring.tld +++ /dev/null @@ -1,399 +0,0 @@ - - - - - 1.1.2 - 1.2 - Spring - http://www.springframework.org/tags - Spring Framework JSP Tag Library. Authors: Rod Johnson, Juergen Hoeller - - - htmlEscape - org.springframework.web.servlet.tags.HtmlEscapeTag - JSP - - Sets default HTML escape value for the current page. - Overrides a "defaultHtmlEscape" context-param in web.xml, if any. - - - defaultHtmlEscape - true - true - Set the default value for HTML escaping, to be put - into the current PageContext. - - - - - - escapeBody - org.springframework.web.servlet.tags.EscapeBodyTag - JSP - - Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - - htmlEscape - false - true - Set HTML escaping for this tag, as boolean value. Overrides the - default HTML escaping setting for the current page. - - - - javaScriptEscape - false - true - Set JavaScript escaping for this tag, as boolean value. - Default is false. - - - - - - message - org.springframework.web.servlet.tags.MessageTag - JSP - - - Retrieves the message with the given code, or text if code isn't resolvable. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - - - message - false - true - A MessageSourceResolvable argument (direct or through JSP EL). - Fits nicely when used in conjunction with Spring's own validation error - classes which all implement the MessageSourceResolvable interface. For - example, this allows you to iterate over all of the errors in a form, - passing each error (using a runtime expression) as the value of this - 'message' attribute, thus effecting the easy display of such error - messages. - - - - - code - false - true - The code (key) to use when looking up the message. - If code is not provided, the text attribute will be used. - - - - - arguments - false - true - Set optional message arguments for this tag, as a - (comma-)delimited String (each String argument can contain JSP EL), - an Object array (used as argument array), or a single Object (used - as single argument). - - - - - argumentSeparator - false - true - The separator character to be used for splitting the - arguments string value; defaults to a 'comma' (','). - - - - - text - false - true - Default text to output when a message for the given code - could not be found. If both text and code are not set, the tag will - output null. - - - - - var - false - true - The string to use when binding the result to the page, - request, session or application scope. If not specified, the result - gets outputted to the writer (i.e. typically directly to the JSP). - - - - - scope - false - true - The scope to use when exporting the result to a variable. - This attribute is only used when var is also set. Possible values are - page, request, session and application. - - - - - htmlEscape - false - true - Set HTML escaping for this tag, as boolean value. - Overrides the default HTML escaping setting for the current page. - - - - - javaScriptEscape - false - true - Set JavaScript escaping for this tag, as boolean value. Default is false. - - - - - - theme - org.springframework.web.servlet.tags.ThemeTag - JSP - - - Retrieves the theme message with the given code, or text if code isn't resolvable. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - - - message - false - true - A MessageSourceResolvable argument (direct or through JSP EL). - - - - code - false - true - The code (key) to use when looking up the message. - If code is not provided, the text attribute will be used. - - - - - arguments - false - true - Set optional message arguments for this tag, as a - (comma-)delimited String (each String argument can contain JSP EL), - an Object array (used as argument array), or a single Object (used - as single argument). - - - - - argumentSeparator - false - true - The separator character to be used for splitting the - arguments string value; defaults to a 'comma' (','). - - - - - text - false - true - Default text to output when a message for the given code - could not be found. If both text and code are not set, the tag will - output null. - - - - - var - false - true - The string to use when binding the result to the page, - request, session or application scope. If not specified, the result - gets outputted to the writer (i.e. typically directly to the JSP). - - - - - scope - false - true - The scope to use when exporting the result to a variable. - This attribute is only used when var is also set. Possible values are - page, request, session and application. - - - - - htmlEscape - false - true - Set HTML escaping for this tag, as boolean value. - Overrides the default HTML escaping setting for the current page. - - - - - javaScriptEscape - false - true - Set JavaScript escaping for this tag, as boolean value. Default is false. - - - - - - hasBindErrors - org.springframework.web.servlet.tags.BindErrorsTag - JSP - - Provides Errors instance in case of bind errors. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - - errors - org.springframework.validation.Errors - - - name - true - true - The name of the bean in the request, that needs to be - inspected for errors. If errors are available for this bean, they - will be bound under the 'errors' key. - - - - htmlEscape - false - true - Set HTML escaping for this tag, as boolean value. - Overrides the default HTML escaping setting for the current page. - - - - - - nestedPath - org.springframework.web.servlet.tags.NestedPathTag - JSP - - Sets a nested path to be used by the bind tag's path. - - - nestedPath - java.lang.String - - - path - true - true - Set the path that this tag should apply. E.g. 'customer' - to allow bind paths like 'address.street' rather than - 'customer.address.street'. - - - - - - bind - org.springframework.web.servlet.tags.BindTag - JSP - - Provides BindStatus object for the given bind path. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - - status - org.springframework.web.servlet.support.BindStatus - - - path - true - true - The path to the bean or bean property to bind status - information for. For instance account.name, company.address.zipCode - or just employee. The status object will exported to the page scope, - specifically for this bean or bean property - - - - ignoreNestedPath - false - true - Set whether to ignore a nested path, if any. Default is to not ignore. - - - htmlEscape - false - true - Set HTML escaping for this tag, as boolean value. Overrides - the default HTML escaping setting for the current page. - - - - - - transform - org.springframework.web.servlet.tags.TransformTag - JSP - - - Provides transformation of variables to Strings, using an appropriate - custom PropertyEditor from BindTag (can only be used inside BindTag). - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a 'defaultHtmlEscape' context-param in web.xml). - - - - value - true - true - The value to transform. This is the actual object you want - to have transformed (for instance a Date). Using the PropertyEditor that - is currently in use by the 'spring:bind' tag. - - - - - var - false - true - The string to use when binding the result to the page, - request, session or application scope. If not specified, the result gets - outputted to the writer (i.e. typically directly to the JSP). - - - - - scope - false - true - The scope to use when exported the result to a variable. - This attribute is only used when var is also set. Possible values are - page, request, session and application. - - - - - htmlEscape - false - true - Set HTML escaping for this tag, as boolean value. Overrides - the default HTML escaping setting for the current page. - - - - - - diff --git a/wise-api/src/main/resources/spring/wisemapping-rest.xml b/wise-api/src/main/resources/spring/wisemapping-rest.xml deleted file mode 100644 index 5c2da2db..00000000 --- a/wise-api/src/main/resources/spring/wisemapping-rest.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - messages - - - - \ No newline at end of file From a681cf9b902f51345ca67301a9c08e3658910945 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 17:21:51 -0800 Subject: [PATCH 054/110] Add user test. --- wise-api/pom.xml | 7 ++ .../com/wisemapping/rest/AdminController.java | 2 +- .../java/com/wisemapping/security/Utils.java | 1 - .../test/rest/RestAccountControllerTest.java | 10 -- .../com/wisemapping/test/rest/RestHelper.java | 12 +++ .../test/rest/RestUserControllerTest.java | 95 +++++++++++++++++++ 6 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java diff --git a/wise-api/pom.xml b/wise-api/pom.xml index 549f5e29..aecf4ca6 100644 --- a/wise-api/pom.xml +++ b/wise-api/pom.xml @@ -174,6 +174,13 @@ compile + + org.springframework.security + spring-security-test + 6.2.1 + test + + io.jsonwebtoken diff --git a/wise-api/src/main/java/com/wisemapping/rest/AdminController.java b/wise-api/src/main/java/com/wisemapping/rest/AdminController.java index 10dd3a2b..3c4d1ac3 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/AdminController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/AdminController.java @@ -69,7 +69,7 @@ public class AdminController extends BaseController { @RequestMapping(method = RequestMethod.POST, value = "/users", consumes = {"application/json"}, produces = {"application/json"}) @ResponseStatus(value = HttpStatus.CREATED) - public void createUser(@RequestBody RestUser user, HttpServletResponse response) throws WiseMappingException { + public void createUser(@RequestBody RestUser user, final HttpServletResponse response) throws WiseMappingException { if (user == null) { throw new IllegalArgumentException("User could not be found"); } diff --git a/wise-api/src/main/java/com/wisemapping/security/Utils.java b/wise-api/src/main/java/com/wisemapping/security/Utils.java index f5c68587..5d93831a 100644 --- a/wise-api/src/main/java/com/wisemapping/security/Utils.java +++ b/wise-api/src/main/java/com/wisemapping/security/Utils.java @@ -34,7 +34,6 @@ final public class Utils { return getUser(false); } - @NotNull public static User getUser(boolean forceCheck) { User result = null; final Authentication auth = SecurityContextHolder.getContext().getAuthentication(); diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java index 689187e5..2a64a3ee 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java @@ -118,14 +118,4 @@ public class RestAccountControllerTest { return templateRest.postForLocation(BASE_REST_URL + "/admin/users", createUserEntity); } - private RestUser createDummyUser() { - final RestUser restUser = new RestUser(); - final String username = "foo-to-delete" + System.nanoTime(); - final String email = username + "@example.org"; - restUser.setEmail(email); - restUser.setFirstname("foo first name"); - restUser.setLastname("foo last name"); - restUser.setPassword("fooPassword"); - return restUser; - } } diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestHelper.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestHelper.java index 23bdacc3..d2538f74 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestHelper.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestHelper.java @@ -1,5 +1,6 @@ package com.wisemapping.test.rest; +import com.wisemapping.rest.model.RestUser; import org.jetbrains.annotations.NotNull; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.client.RestTemplateBuilder; @@ -22,4 +23,15 @@ public class RestHelper { result.setContentType(mediaType); return result; } + + static RestUser createDummyUser() { + final RestUser restUser = new RestUser(); + final String username = "foo-to-delete" + System.nanoTime(); + final String email = username + "@example.org"; + restUser.setEmail(email); + restUser.setFirstname("foo first name"); + restUser.setLastname("foo last name"); + restUser.setPassword("fooPassword"); + return restUser; + } } diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java new file mode 100644 index 00000000..49320e36 --- /dev/null +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java @@ -0,0 +1,95 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.wisemapping.test.rest; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.wisemapping.config.common.CommonConfig; +import com.wisemapping.config.rest.RestAppConfig; +import com.wisemapping.model.User; +import com.wisemapping.rest.UserController; +import com.wisemapping.rest.model.RestUser; +import com.wisemapping.service.UserService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; +import org.springframework.test.web.servlet.MockMvc; + +import static com.wisemapping.test.rest.RestHelper.createDummyUser; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, UserController.class}) +@AutoConfigureMockMvc +public class RestUserControllerTest { + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private UserService userService; + + + private RestUser createUser() throws Exception { + final RestUser result = createDummyUser(); + final String userJson = objectMapper.writeValueAsString(result); + + mockMvc.perform( + post("/api/restfull/admin/users"). + contentType(MediaType.APPLICATION_JSON) + .content(userJson) + .with(user("test@wisemapping.org").roles("ADMIN"))) + .andExpect(status().isCreated()); + + // Check dao ... + User userBy = userService.getUserBy(result.getEmail()); + assertTrue(userBy!=null); + return result; + } + + @Test + void resetPasswordInvalidUser() throws Exception { + this.mockMvc.perform + (put("/api/restfull/users/resetPassword?email=doesnotexist@example.com")) + .andDo(print()) + .andExpect(status().is4xxClientError()) + .andExpect(content().string(containsString("The email provided is not a valid user account."))); + } + + @Test + void resetPasswordValidUser() throws Exception { + final RestUser user = createUser(); + this.mockMvc.perform + (put("/api/restfull/users/resetPassword?email=" + user.getEmail())) + .andDo(print()) + .andExpect(status().isOk()); + } +} From 6674c607f7ab2c21679ffb33f8f74c352d63bf51 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 17:31:21 -0800 Subject: [PATCH 055/110] Add registration test. --- .../rest/model/RestUserRegistration.java | 11 ++++++++ .../test/rest/RestUserControllerTest.java | 25 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/wise-api/src/main/java/com/wisemapping/rest/model/RestUserRegistration.java b/wise-api/src/main/java/com/wisemapping/rest/model/RestUserRegistration.java index dca77ea3..3b0fb7d0 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/model/RestUserRegistration.java +++ b/wise-api/src/main/java/com/wisemapping/rest/model/RestUserRegistration.java @@ -24,6 +24,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.wisemapping.model.User; +import java.awt.*; + @JsonAutoDetect( fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY, @@ -47,6 +49,15 @@ public class RestUserRegistration { return user; } + public static RestUserRegistration create(String email, String password, String firstname, String lastname) { + final RestUserRegistration result = new RestUserRegistration(); + result.email = email; + result.password = password; + result.firstname = firstname; + result.lastname = lastname; + return result; + } + public String getEmail() { return email; } diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java index 49320e36..f487c19e 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java @@ -25,8 +25,10 @@ import com.wisemapping.config.rest.RestAppConfig; import com.wisemapping.model.User; import com.wisemapping.rest.UserController; import com.wisemapping.rest.model.RestUser; +import com.wisemapping.rest.model.RestUserRegistration; import com.wisemapping.service.UserService; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -37,6 +39,7 @@ import org.springframework.test.web.servlet.MockMvc; import static com.wisemapping.test.rest.RestHelper.createDummyUser; import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -71,7 +74,7 @@ public class RestUserControllerTest { // Check dao ... User userBy = userService.getUserBy(result.getEmail()); - assertTrue(userBy!=null); + assertNotNull(userBy); return result; } @@ -92,4 +95,24 @@ public class RestUserControllerTest { .andDo(print()) .andExpect(status().isOk()); } + + + @Test + @Disabled + void registerNewUser() throws Exception { + final RestUserRegistration user = RestUserRegistration.create("some@example.com", "somepass", "Test", "registation"); + final String userJson = objectMapper.writeValueAsString(user); + + mockMvc.perform( + post("/api/restfull/users/"). + contentType(MediaType.APPLICATION_JSON) + .content(userJson)) + .andExpect(status().isCreated()); + + // Check dao ... + User userBy = userService.getUserBy(user.getEmail()); + assertNotNull(userBy); + } + + } From 069943cf3067eaeee118f57860cfa8c78ae3506e Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 18:28:23 -0800 Subject: [PATCH 056/110] Add first version of token generation. --- .../db/wisemapping.properties | 5 + .../db/wisemapping.script | 344 ++++++++++++++++++ .../config/rest/RestAppConfig.java | 1 + .../wisemapping/rest/JwtAuthController.java | 75 ++++ .../wisemapping/rest/model/RestJwtUser.java | 60 +++ .../wisemapping/security/JwtTokenUtil.java | 61 ++++ .../security/UserDetailsService.java | 2 +- .../service/MindmapServiceImpl.java | 2 +- wise-api/src/main/resources/application.yml | 12 +- .../test/rest/RestJwtAuthControllerTest.java | 98 +++++ 10 files changed, 653 insertions(+), 7 deletions(-) create mode 100644 wise-api/${database.base.url}/db/wisemapping.properties create mode 100644 wise-api/${database.base.url}/db/wisemapping.script create mode 100644 wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java create mode 100644 wise-api/src/main/java/com/wisemapping/rest/model/RestJwtUser.java create mode 100644 wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java create mode 100644 wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java diff --git a/wise-api/${database.base.url}/db/wisemapping.properties b/wise-api/${database.base.url}/db/wisemapping.properties new file mode 100644 index 00000000..6806b69c --- /dev/null +++ b/wise-api/${database.base.url}/db/wisemapping.properties @@ -0,0 +1,5 @@ +#HSQL Database Engine 2.7.1 +#Sun Feb 04 18:28:11 PST 2024 +modified=yes +tx_timestamp=992 +version=2.7.1 diff --git a/wise-api/${database.base.url}/db/wisemapping.script b/wise-api/${database.base.url}/db/wisemapping.script new file mode 100644 index 00000000..8157e5ab --- /dev/null +++ b/wise-api/${database.base.url}/db/wisemapping.script @@ -0,0 +1,344 @@ +SET DATABASE UNIQUE NAME HSQLDB8D7714344E +SET DATABASE DEFAULT RESULT MEMORY ROWS 0 +SET DATABASE EVENT LOG LEVEL 0 +SET DATABASE TRANSACTION CONTROL LOCKS +SET DATABASE DEFAULT ISOLATION LEVEL READ COMMITTED +SET DATABASE TRANSACTION ROLLBACK ON CONFLICT TRUE +SET DATABASE TEXT TABLE DEFAULTS '' +SET DATABASE SQL NAMES FALSE +SET DATABASE SQL RESTRICT EXEC FALSE +SET DATABASE SQL REFERENCES FALSE +SET DATABASE SQL SIZE TRUE +SET DATABASE SQL TYPES FALSE +SET DATABASE SQL TDC DELETE TRUE +SET DATABASE SQL TDC UPDATE TRUE +SET DATABASE SQL SYS INDEX NAMES TRUE +SET DATABASE SQL CONCAT NULLS TRUE +SET DATABASE SQL UNIQUE NULLS TRUE +SET DATABASE SQL CONVERT TRUNCATE TRUE +SET DATABASE SQL AVG SCALE 0 +SET DATABASE SQL DOUBLE NAN TRUE +SET DATABASE SQL SYNTAX MYS TRUE +SET FILES WRITE DELAY 500 MILLIS +SET FILES BACKUP INCREMENT TRUE +SET FILES CACHE SIZE 10000 +SET FILES CACHE ROWS 50000 +SET FILES SCALE 32 +SET FILES LOB SCALE 32 +SET FILES DEFRAG 0 +SET FILES NIO TRUE +SET FILES NIO SIZE 256 +SET FILES LOG TRUE +SET FILES LOG SIZE 50 +SET FILES CHECK 992 +SET DATABASE COLLATION "SQL_TEXT" PAD SPACE +CREATE USER SA PASSWORD DIGEST 'd41d8cd98f00b204e9800998ecf8427e' +ALTER USER SA SET LOCAL TRUE +CREATE SCHEMA PUBLIC AUTHORIZATION DBA +CREATE MEMORY TABLE PUBLIC.COLLABORATOR(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,EMAIL VARCHAR(255) NOT NULL,CREATION_DATE DATE,UNIQUE(EMAIL)) +ALTER TABLE PUBLIC.COLLABORATOR ALTER COLUMN ID RESTART WITH 41 +CREATE MEMORY TABLE PUBLIC.USER(COLABORATOR_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,AUTHENTICATION_TYPE CHARACTER(1) NOT NULL,AUTHENTICATOR_URI VARCHAR(255),FIRSTNAME VARCHAR(255) NOT NULL,LASTNAME VARCHAR(255) NOT NULL,PASSWORD VARCHAR(255) NOT NULL,ACTIVATION_CODE BIGINT NOT NULL,ACTIVATION_DATE DATE,ALLOW_SEND_EMAIL CHARACTER(1) NOT NULL,LOCALE VARCHAR(5),GOOGLE_SYNC BOOLEAN,SYNC_CODE VARCHAR(255),GOOGLE_TOKEN VARCHAR(255),FOREIGN KEY(COLABORATOR_ID) REFERENCES PUBLIC.COLLABORATOR(ID)) +ALTER TABLE PUBLIC.USER ALTER COLUMN COLABORATOR_ID RESTART WITH 41 +CREATE MEMORY TABLE PUBLIC.MINDMAP(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,TITLE VARCHAR(255) NOT NULL,DESCRIPTION VARCHAR(255),XML VARBINARY(16777216) NOT NULL,PUBLIC BOOLEAN NOT NULL,CREATION_DATE TIMESTAMP,EDITION_DATE TIMESTAMP,CREATOR_ID INTEGER NOT NULL,LAST_EDITOR_ID INTEGER NOT NULL) +ALTER TABLE PUBLIC.MINDMAP ALTER COLUMN ID RESTART WITH 67 +CREATE MEMORY TABLE PUBLIC.LABEL(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,TITLE VARCHAR(30),CREATOR_ID INTEGER NOT NULL,PARENT_LABEL_ID INTEGER,COLOR VARCHAR(7) NOT NULL) +ALTER TABLE PUBLIC.LABEL ALTER COLUMN ID RESTART WITH 5 +CREATE MEMORY TABLE PUBLIC.R_LABEL_MINDMAP(MINDMAP_ID INTEGER NOT NULL,LABEL_ID INTEGER NOT NULL,PRIMARY KEY(MINDMAP_ID,LABEL_ID),FOREIGN KEY(MINDMAP_ID) REFERENCES PUBLIC.MINDMAP(ID),FOREIGN KEY(LABEL_ID) REFERENCES PUBLIC.LABEL(ID) ON DELETE CASCADE) +CREATE MEMORY TABLE PUBLIC.MINDMAP_HISTORY(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,XML VARBINARY(16777216) NOT NULL,MINDMAP_ID INTEGER NOT NULL,CREATION_DATE TIMESTAMP,EDITOR_ID INTEGER NOT NULL,FOREIGN KEY(MINDMAP_ID) REFERENCES PUBLIC.MINDMAP(ID)) +ALTER TABLE PUBLIC.MINDMAP_HISTORY ALTER COLUMN ID RESTART WITH 7 +CREATE MEMORY TABLE PUBLIC.COLLABORATION_PROPERTIES(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,STARRED BOOLEAN NOT NULL,MINDMAP_PROPERTIES VARCHAR(512)) +ALTER TABLE PUBLIC.COLLABORATION_PROPERTIES ALTER COLUMN ID RESTART WITH 74 +CREATE MEMORY TABLE PUBLIC.COLLABORATION(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,COLABORATOR_ID INTEGER NOT NULL,PROPERTIES_ID INTEGER NOT NULL,MINDMAP_ID INTEGER NOT NULL,ROLE_ID INTEGER NOT NULL,FOREIGN KEY(COLABORATOR_ID) REFERENCES PUBLIC.COLLABORATOR(ID),FOREIGN KEY(MINDMAP_ID) REFERENCES PUBLIC.MINDMAP(ID),FOREIGN KEY(PROPERTIES_ID) REFERENCES PUBLIC.COLLABORATION_PROPERTIES(ID)) +ALTER TABLE PUBLIC.COLLABORATION ALTER COLUMN ID RESTART WITH 74 +CREATE MEMORY TABLE PUBLIC.ACCESS_AUDITORY(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,USER_ID INTEGER NOT NULL,LOGIN_DATE DATE,FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(COLABORATOR_ID) ON DELETE CASCADE) +ALTER TABLE PUBLIC.ACCESS_AUDITORY ALTER COLUMN ID RESTART WITH 0 +ALTER SEQUENCE SYSTEM_LOBS.LOB_ID RESTART WITH 1 +SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CARDINAL_NUMBER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.YES_OR_NO TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CHARACTER_DATA TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.SQL_IDENTIFIER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.TIME_STAMP TO PUBLIC +GRANT DBA TO SA +SET SCHEMA SYSTEM_LOBS +INSERT INTO BLOCKS VALUES(0,2147483647,0) +SET SCHEMA PUBLIC +INSERT INTO COLLABORATOR VALUES(1,'test@wisemapping.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(2,'admin@wisemapping.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(3,'foo-to-delete1095503453352583@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(4,'foo-to-delete1095504838563541@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(5,'foo-to-delete1095505168712666@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(6,'foo-to-delete1095505810331125@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(8,'foo-to-delete1095507564789583@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(9,'foo-to-delete1095509185883583@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(10,'foo-to-delete1095510144202500@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(11,'foo-to-delete1095512040923666@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(12,'new-collab@example.com','2024-02-04') +INSERT INTO COLLABORATOR VALUES(13,'foo-to-delete1095513302479041@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(14,'foo-to-delete1095514551101291@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(15,'foo-to-delete1095515506054708@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(16,'foo-to-delete1095516166443791@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(17,'foo-to-delete1095517157929916@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(18,'another-collab@example.com','2024-02-04') +INSERT INTO COLLABORATOR VALUES(19,'foo-to-delete1095519033584291@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(20,'foo-to-delete1095520924763291@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(21,'foo-to-delete1095522170804250@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(22,'foo-to-delete1095523103464166@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(23,'foo-to-delete1095524343860250@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(24,'foo-to-delete1095527193855625@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(25,'foo-to-delete1095528435850666@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(26,'foo-to-delete1095529692935041@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(27,'foo-to-delete1095531562488791@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(28,'foo-to-delete1095532816384416@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(29,'foo-to-delete1095534077960000@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(30,'foo-to-delete1095536060733875@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(31,'foo-to-delete1095537826621458@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(32,'foo-to-delete1095539107013833@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(33,'foo-to-delete1095540287897833@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(34,'foo-to-delete1095541404608166@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(35,'foo-to-delete1095542691628458@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(36,'foo-to-delete1095543993678916@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(37,'foo-to-delete1095545009514416@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(38,'foo-to-delete1095545990485750@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(39,'foo-to-delete1095547256374750@example.org','2024-02-04') +INSERT INTO COLLABORATOR VALUES(40,'foo-to-delete1095548781024250@example.org','2024-02-04') +INSERT INTO USER VALUES(1,'D',NULL,'Test','User','ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3',1237,'2024-02-04','1',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(2,'D',NULL,'Admin','User','ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3',1237,'2024-02-04','1',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(3,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$TX8Pjoa4ulpGuHdlXY5ax.dTQrdhBvbVTWIM3MfpBoO3zBeoplHl6',-4850015659903415425,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(4,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$bLo7xEJuQuoCMTCKYdoINewk4Mm0mzN3SEDk499MUNkLqUB/vA8OW',-8352090659676303034,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(5,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$cv8hHr/zoVlG0HUWKiijv.mKJxTWfsNLL0dHM3THst6p4E7Jgzpw2',-6036910863989637121,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(6,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$gRV7wdtrBnFvn.emYT6CTuJB7GWMGFn2AzXvJUD7acJ5LgKS2oiXi',-8568901134768544702,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(8,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$UZAhmFoGXhCiCkvUNIS4GuZ1uEWjKxZBMzp5TQq0QaYXNKoKw0h/m',-8295815163365799267,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(9,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$AzXTttUaES.gFJSu3.sUQemZDWFTr4T6ioptclM8PlVwDxr8HqniO',-5397813652597351155,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(10,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$W9FUJhA8f70D.7HIbSBva.MepMnChErqNGL8/BXgZZWH07NRnvWL2',-7544650540467244908,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(11,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$ShthGXm75P1q7UjiL6vT3.mxfTqu/gAGdT4ixyaie3dI./HTDRXp6',-7889606868798742570,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(13,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$4/8N2lm7qnFZZMl3emRGj.H94GHNRR/OUeXosXPhoby2XJgD1uDXC',-7268335255585620308,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(14,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$auyw0LUob2ZvQjHnkUPAK.WwSKthFTwMxdmLxsFOBJQw6Rz5eKgjW',-4859760027220123933,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(15,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$mOgC/KvhkICw0HcgSPOx7.AUIb6awLT.jdOMjT41VueeRylA5H.Z2',-8379618723328975557,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(16,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$dGuajA6k/TJ9h/7TgwYheuXkvggOutT4ZwP./Du3FuNdOy5hW20QK',-5844770767303893147,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(17,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$e6aVGr94W/qynvODuk/Wsu.hjH3bsGeR3.TlEkV2oHDrig9fUGpaq',-8583719471462548065,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(19,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$a6ZsOVlI80B3qL1qXIR1C.6bOrZAajfcI.P8QOVDjRfUwyb6kz4Pa',-6844205299178825206,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(20,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$IVnbFIfkP7UGmIx7lP9bAO9udtyjXRTOR.c4eMp.aGyvFG.QdLfhy',-6297938040158171470,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(21,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$3u8r0ruJmhj15HBRhYjRA.6pnme71QosWQujwAFoR6QDrraxxulK6',-5783544984352539928,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(22,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$xOunjQvmPEbQx0HZOmzhvOmdpXEKI2rQZN0yegH8rlMDoK5NX8Qny',-5700156451683586162,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(23,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$mdFPUQ8hcJsu7tCpVKRb4es8wOo/VI1Qo30IfVeQzOcdugeJq3mN.',-7615810263780338939,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(24,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$OwTgW8Cwam.eWhVOJ1FH9./.xiVzCU5iutXaaLkJihkx5L4xOtcxS',-5727811444992568492,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(25,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$9jMjvDrrfCDj.PuFT9IpKeZACRF56sSSP1SwlhL5kLwAC7s7SgvXa',-5793072758750432848,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(26,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$G.6f9UJAtyFd9tSt9LZ0W.v4XH3VpMmUF7zhnICu70fTk5NhEqls2',-9172141193380704830,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(27,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$CI/aeAwL2aiwXMxZaxVGJ.icl2TZqBePLVwZUL/1cqWQK7pINWWE2',-5834501834858404373,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(28,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$Prit/d2Mpo4phHAK0ALumu0oUwRMZyrcP.7D5WSkavQzotB3VYJMi',-5937808155108140865,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(29,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$1jzMy7/E7UwrwK.pVtyIOOHDiH9l8EymcYdGHGBJptRNNpzYCje4q',-9177769807106770742,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(30,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$uTzqaCht0Rph/vws4cUziea6azU78gDUBo1xIGGWZV7BLfi5U.Y.q',-8111317027341093629,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(31,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$Gp2HGMmn3MrfABRsrTJiFe/S.LPQikJhFMse7O.hRTnNvRdeKTBbO',-5277431289150781474,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(32,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$HLkQd4gXaj0EbH/BSKBDMeqK9hVtLuo1HR8/DlN1xkYLFG34R1a9q',-8979411792095495717,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(33,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$8KHuDAkByNzMuMAaXA4tVuJNEyZY6Fi9UwMfEFPxNby0GbvmYZhTG',-6697485127552960846,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(34,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$TtVJlYYIfKMgBoNCgQpPrOEVhBfhE/D7P3NAAsqFc/g9GgiwZMnPa',-8668916251663383176,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(35,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$1ahc8uZFPiPh2XaGejoiweB3asNvRAzlJKokutFBczKTh4/G9rwo6',-5329239724338752792,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(36,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$omerC2OpRJ7QhSMfABXx7OOdpV51QkysVrU0W9Qw2rfOSZmC/z02.',-6023724487699956165,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(37,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$IztIOSJDDJxbDYiAKmEMnuOSSuz6bGQPp5twZeGXQnLmqGZEAqQd.',-5119440034016837315,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(38,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$QiblVCcv.pWfZt0pHgBdLOj1896OHTZG1t0ADubHMgmANS1Smyj0G',-6920785024573180477,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(39,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$Gu0N.1TlBLxZ/guyb4rXeOSJAoGMC19uqczSYbf2nB8elV6VMfdgi',-5776845727120034520,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO USER VALUES(40,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$CBmNnCT1y3d9SjX5tuGLROp6ml0GDS1fRaTGTfJ4baCFu.3crS5FO',-8203322937841654308,'2024-02-04','0',NULL,NULL,NULL,NULL) +INSERT INTO MINDMAP VALUES(0,'Welcome foo first name','','504b03041400080808000f93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808000f934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:30.682000','2024-02-04 18:24:30.682000',3,3) +INSERT INTO MINDMAP VALUES(1,'deleteWithoutOwnerPermission',NULL,'504b03041400080808000f93445800000000000000000000000007000000636f6e74656e7415cccb0d80201005c056c8366003400b7af34cf04537e1976551cb17ef93b1393473433ad7e24843392b19bd90e1a809f74cde6a6d1c4d4451096922199806af3a3a90a0d859af3a747d0a648364ee7f478bb7cbecfd07504b0708c6e2041f5700000064000000504b010214001400080808000f934458c6e2041f5700000064000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008c0000000000',FALSE,'2024-02-04 18:24:31.049000','2024-02-04 18:24:31.049000',3,3) +INSERT INTO MINDMAP VALUES(2,'Welcome foo first name','','504b03041400080808000f93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808000f934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:31.378000','2024-02-04 18:24:31.378000',4,4) +INSERT INTO MINDMAP VALUES(3,'Welcome foo first name','','504b03041400080808000f93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808000f934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:31.700000','2024-02-04 18:24:31.700000',5,5) +INSERT INTO MINDMAP VALUES(4,'Welcome foo first name','','504b03041400080808001093445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080010934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:32.357000','2024-02-04 18:24:32.357000',6,6) +INSERT INTO MINDMAP VALUES(5,'verifyMapOwnership Map user 1',NULL,'504b03041400080808001093445800000000000000000000000007000000636f6e74656e740d8cdb0980300c0057095940fc6fbb813843295103b60d697c6d6f3e0fee2ed42c70930eee2da2e5b677043ba85244511e1553b02e5ca05033cda74b7a913bf45a442f79fb962cebd37c72b080035c8314669c5298fc9f7e504b07085f0580fb5800000065000000504b01021400140008080800109344585f0580fb5800000065000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008d0000000000',FALSE,'2024-02-04 18:24:32.713000','2024-02-04 18:24:32.713000',6,6) +INSERT INTO MINDMAP VALUES(8,'Welcome foo first name','','504b03041400080808001193445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080011934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:34.105000','2024-02-04 18:24:34.105000',8,8) +INSERT INTO MINDMAP VALUES(9,'Update sample ',NULL,'504b03041400080808001193445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080011934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',FALSE,'2024-02-04 18:24:34.449000','2024-02-04 18:24:34.768000',8,8) +INSERT INTO MINDMAP VALUES(10,'Welcome foo first name','','504b03041400080808001193445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080011934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:35.719000','2024-02-04 18:24:35.719000',9,9) +INSERT INTO MINDMAP VALUES(11,'addCollabWhitOwnerRole',NULL,'504b03041400080808001293445800000000000000000000000007000000636f6e74656e740dcccb0d80200c00d05548177001e0e200265e3c576884042829f533bedc5f9eadd8cd43323237078aed62309aa892832e7954f056b9e7600235152c13c94dd3d0a70e30c6954bc1f34859b7b791ec5c08166f9719fb1f504b0708d1486f3d570000005e000000504b0102140014000808080012934458d1486f3d570000005e000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008c0000000000',FALSE,'2024-02-04 18:24:36.046000','2024-02-04 18:24:36.046000',9,9) +INSERT INTO MINDMAP VALUES(12,'Welcome foo first name','','504b03041400080808001293445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080012934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:36.681000','2024-02-04 18:24:36.681000',10,10) +INSERT INTO MINDMAP VALUES(13,'removeLabelFromMindmap',NULL,'504b03041400080808001293445800000000000000000000000007000000636f6e74656e740dccc10d80200c46e15548177001e0e8498740fca3249492528de3cbe95dbe3ccfa9bb173a8ab44096da25e4ec062350d73298a237e925bb8c669aea44fa601a7c1648c1f2624b07eaaac27b69e71cd212fd321b7f504b070811bf9114550000005e000000504b010214001400080808001293445811bf9114550000005e000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008a0000000000',FALSE,'2024-02-04 18:24:37.317000','2024-02-04 18:24:37.317000',10,10) +INSERT INTO MINDMAP VALUES(14,'Welcome foo first name','','504b03041400080808001393445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080013934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:38.576000','2024-02-04 18:24:38.576000',11,11) +INSERT INTO MINDMAP VALUES(15,'Map for addCollabs - ',NULL,'504b03041400080808001393445800000000000000000000000007000000636f6e74656e740dccc10d80200c40d1559ade0d0b0017cf0e51b12a095052aa717cb9bfff7da50e2febc8d2021ab54b10ece6ca01bbe651317a939e13246ea65426d287a7e1cf026eb33e45818e639552681f000ba08bdecd71fc01504b07085e2e2812550000005e000000504b01021400140008080800139344585e2e2812550000005e000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008a0000000000',FALSE,'2024-02-04 18:24:38.897000','2024-02-04 18:24:38.897000',11,11) +INSERT INTO MINDMAP VALUES(16,'Welcome foo first name','','504b03041400080808001393445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080013934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:39.830000','2024-02-04 18:24:39.830000',13,13) +INSERT INTO MINDMAP VALUES(17,'Update XML sample',NULL,'504b03041400080808001493445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080014934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',FALSE,'2024-02-04 18:24:40.146000','2024-02-04 18:24:40.456000',13,13) +INSERT INTO MINDMAP VALUES(18,'Welcome foo first name','','504b03041400080808001493445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080014934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:41.102000','2024-02-04 18:24:41.102000',14,14) +INSERT INTO MINDMAP VALUES(19,'Map for deleteOwnerCollab',NULL,'504b03041400080808001493445800000000000000000000000007000000636f6e74656e740dcccb0d80201045d156c8346003c0c6b5b106c4a792004386f153beeccfbdb684661e484f5c1d69a82793d10b058e9aa45ec85be596a289a82a210f243786c1a78e96511f2c664786627d2b64e69cc34693b7d378fb1f504b0708950dc3915700000061000000504b0102140014000808080014934458950dc3915700000061000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008c0000000000',FALSE,'2024-02-04 18:24:41.414000','2024-02-04 18:24:41.414000',14,14) +INSERT INTO MINDMAP VALUES(20,'Welcome foo first name','','504b03041400080808001593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080015934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:42.033000','2024-02-04 18:24:42.033000',15,15) +INSERT INTO MINDMAP VALUES(21,'MaddCollabWhitoutOwnerPermission',NULL,'504b03041400080808001593445800000000000000000000000007000000636f6e74656e7415cd310ec3200c40d1ab205f20170096ce55b3657689152c0146c6b43d7ee8fef4bfafd8dd8774b0b40086ed127096a95280ae3c2a446fd239b944cd14cb423a6919fa5980279ee7434ac1f791d964daebdb4877d2cae39f842dfa6d2de20d504b0708951b63065f00000068000000504b0102140014000808080015934458951b63065f00000068000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000940000000000',FALSE,'2024-02-04 18:24:42.364000','2024-02-04 18:24:42.364000',15,15) +INSERT INTO MINDMAP VALUES(22,'Welcome foo first name','','504b03041400080808001593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080015934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:42.755000','2024-02-04 18:24:42.755000',16,16) +INSERT INTO MINDMAP VALUES(23,'Welcome foo first name','','504b03041400080808001593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080015934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:43.695000','2024-02-04 18:24:43.695000',17,17) +INSERT INTO MINDMAP VALUES(24,'Map for updateCollabs',NULL,'504b03041400080808001693445800000000000000000000000007000000636f6e74656e740dccc10d80200c40d15548176001e0e2d9212a5625014a4a318e6fefefffd070b8976416ee1114fbcde0f4a146118694d92005e551b2cbd455b01a924566e8d308bbd5178b5be344a58d6bc563824fc1db37fd504b07082f650996530000005d000000504b01021400140008080800169344582f650996530000005d000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000880000000000',FALSE,'2024-02-04 18:24:44.008000','2024-02-04 18:24:44.008000',17,17) +INSERT INTO MINDMAP VALUES(28,'Welcome foo first name','','504b03041400080808001793445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080017934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:47.456000','2024-02-04 18:24:47.456000',20,20) +INSERT INTO MINDMAP VALUES(30,'Welcome foo first name','','504b03041400080808001893445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080018934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:48.698000','2024-02-04 18:24:48.698000',21,21) +INSERT INTO MINDMAP VALUES(31,'Map to Validate Creation',NULL,'504b03041400080808001893445800000000000000000000000007000000636f6e74656e740dccbb0d80300c00d1552c2f90059234d4b4f456b0c0527e720c627cdcbfbbd868c2cbba64f48446fd1a087673e384536535ccd1c6940285bb295547fab01bfe2ce1eeb50d38a8ca49c6b02993f90a438ec1d7f907504b0708d90b4c985500000060000000504b0102140014000808080018934458d90b4c985500000060000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008a0000000000',FALSE,'2024-02-04 18:24:49.012000','2024-02-04 18:24:49.012000',21,21) +INSERT INTO MINDMAP VALUES(32,'Welcome foo first name','','504b03041400080808001893445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080018934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:49.631000','2024-02-04 18:24:49.631000',22,22) +INSERT INTO MINDMAP VALUES(33,'New map to change title - application/json',NULL,'504b03041400080808001893445800000000000000000000000007000000636f6e74656e740dccd109c0200c45d1554216700175830e2112aaa046e26be9f8cdff3d37ceb2e9153b5d576294752b139a4c49bcad9fc9394277af5465c1caf0c81ef1463e24be5c43a9368742e818c221c7e0d7fc03504b07080bfb1a9e500000005b000000504b01021400140008080800189344580bfb1a9e500000005b000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000850000000000',FALSE,'2024-02-04 18:24:49.941000','2024-02-04 18:24:49.941000',22,22) +INSERT INTO MINDMAP VALUES(34,'Welcome foo first name','','504b03041400080808001993445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080019934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:50.882000','2024-02-04 18:24:50.882000',23,23) +INSERT INTO MINDMAP VALUES(35,'map to test revert changes',NULL,'504b03041400080808001993445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a2c43c858adc1c85927ca078718942516a596a5189427246625e7a6ab142716a51596672aaba9d8d3ec80000504b070851cb12a34300000046000000504b010214001400080808001993445851cb12a34300000046000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000780000000000',FALSE,'2024-02-04 18:24:51.195000','2024-02-04 18:24:52.481000',23,23) +INSERT INTO MINDMAP VALUES(36,'Welcome foo first name','','504b03041400080808001a93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001a934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:53.724000','2024-02-04 18:24:53.724000',24,24) +INSERT INTO MINDMAP VALUES(37,'Map to change Description ','New map to change description ','504b03041400080808001b93445800000000000000000000000007000000636f6e74656e740dccc10dc0200840d155080bb8807aeab5431842aa491582b4e9f8e5fedfcfb329bc6c7bc82ae86d5d82e09d2717541b7b62cd2e3a0888975bbb23b287a3e1cf0b9ea15d807a40868337d9508f1760aa39c5bcfe504b07087246c8a85400000062000000504b010214001400080808001b9344587246c8a85400000062000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000890000000000',FALSE,'2024-02-04 18:24:54.041000','2024-02-04 18:24:54.041000',24,24) +INSERT INTO MINDMAP VALUES(38,'Welcome foo first name','','504b03041400080808001b93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001b934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:54.970000','2024-02-04 18:24:54.970000',25,25) +INSERT INTO MINDMAP VALUES(39,'Map to change title',NULL,'504b03041400080808001b93445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b010214001400080808001b934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',FALSE,'2024-02-04 18:24:55.289000','2024-02-04 18:24:55.606000',25,25) +INSERT INTO MINDMAP VALUES(40,'Welcome foo first name','','504b03041400080808001c93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001c934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:56.221000','2024-02-04 18:24:56.221000',26,26) +INSERT INTO MINDMAP VALUES(41,'Map for deleteCollabs - ',NULL,'504b03041400080808001c93445800000000000000000000000007000000636f6e74656e740dcc410e80200c05d1ab34dd1b2f006c5c7b08d4af920025a51a8f2ffb37e34a6cf4427b92ead962bd84c96e14786e9a7ae1e04c5ada6947358d79207d300c3ef3bc8efa14a503198645728e5b279a88e7e0e6f10e3f504b070860b5a1da5600000061000000504b010214001400080808001c93445860b5a1da5600000061000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008b0000000000',FALSE,'2024-02-04 18:24:56.534000','2024-02-04 18:24:56.534000',26,26) +INSERT INTO MINDMAP VALUES(42,'Welcome foo first name','','504b03041400080808001d93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001d934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:58.091000','2024-02-04 18:24:58.091000',27,27) +INSERT INTO MINDMAP VALUES(43,'Stared Map user 1',NULL,'504b03041400080808001d93445800000000000000000000000007000000636f6e74656e740dcccd0d80200c06d0559a2e40bc031b78728206bf2889fca414e3f8727f79be48a7173a72ab814dead598ec4641e0ae79148ede5acf8912aaa93c0be9c432f82cf061a238695fc91c50dad845efd6197f504b0708cc8a306c5100000059000000504b010214001400080808001d934458cc8a306c5100000059000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000860000000000',FALSE,'2024-02-04 18:24:58.402000','2024-02-04 18:24:58.402000',27,27) +INSERT INTO MINDMAP VALUES(44,'Welcome foo first name','','504b03041400080808001d93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001d934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:59.351000','2024-02-04 18:24:59.351000',28,28) +INSERT INTO MINDMAP VALUES(45,'Map to clone sample ',NULL,'504b03041400080808001d93445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a24485e49cfcbcd41405a002753b1b7d903a00504b070843b305852a0000002d000000504b010214001400080808001d93445843b305852a0000002d000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005f0000000000',FALSE,'2024-02-04 18:24:59.661000','2024-02-04 18:24:59.661000',28,28) +INSERT INTO MINDMAP VALUES(46,'Cloned map but with previous content.','Cloned map desc','504b03041400080808001d93445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a24485e49cfcbcd41405a002753b1b7d903a00504b070843b305852a0000002d000000504b010214001400080808001d93445843b305852a0000002d000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005f0000000000',FALSE,'2024-02-04 18:24:59.983000','2024-02-04 18:24:59.983000',28,28) +INSERT INTO MINDMAP VALUES(47,'Welcome foo first name','','504b03041400080808002093445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080020934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:00.609000','2024-02-04 18:25:00.609000',29,29) +INSERT INTO MINDMAP VALUES(48,'Map for updateCollabType',NULL,'504b03041400080808002093445800000000000000000000000007000000636f6e74656e740dccc10d80200c40d15548176001e0e2d99b0b54ad4a02b4a9c5e8f6727fff878ae21ed23b738b60d84e066717558a209aef0a29184bdedc46cd14cb40da69187a2dc23cea83d575d9d168e252705d3e21f029f8b14e3f504b07081154cf865700000060000000504b01021400140008080800209344581154cf865700000060000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008c0000000000',FALSE,'2024-02-04 18:25:00.932000','2024-02-04 18:25:00.932000',29,29) +INSERT INTO MINDMAP VALUES(49,'Welcome foo first name','','504b03041400080808002193445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080021934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:02.656000','2024-02-04 18:25:02.656000',30,30) +INSERT INTO MINDMAP VALUES(50,'Maps 1 - ',NULL,'504b03041400080808002193445800000000000000000000000007000000636f6e74656e740dccc109c0200c05d0553eb917e95ddda0430409ad5035c4b474fc7a7fbcd858f18acd3a7a22e77e0e825fd224915a9d8d72f4a1b5a04877e37b217b6419f93cd1c13ab1031b28e41856967f504b070886439d2e4c00000052000000504b010214001400080808002193445886439d2e4c00000052000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000810000000000',FALSE,'2024-02-04 18:25:03.353000','2024-02-04 18:25:03.353000',30,30) +INSERT INTO MINDMAP VALUES(51,'Welcome foo first name','','504b03041400080808002293445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080022934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:04.361000','2024-02-04 18:25:04.361000',31,31) +INSERT INTO MINDMAP VALUES(52,'List Maps 1',NULL,'504b03041400080808002293445800000000000000000000000007000000636f6e74656e740dccc10980300c00c055421628fedb4ea04384123460db9044717cfb3f2e775278d95ce6281834ce891017772ea826deb1e6982a0d1a8f30ba17b28797e12f0aeee20107a9c386a9e6b4b6fa03504b07087e877a764d00000053000000504b01021400140008080800229344587e877a764d00000053000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000820000000000',FALSE,'2024-02-04 18:25:04.675000','2024-02-04 18:25:04.675000',31,31) +INSERT INTO MINDMAP VALUES(53,'List Maps 2',NULL,'504b03041400080808002293445800000000000000000000000007000000636f6e74656e740dccc10980300c00c055421628f86e3b810e114ad0806d4312c5f1edffb8dc49e1657399a360d03827425cdcb9a09a78c79a63aa34683cc2e85ec81e5e86bf28b88b071ca40e1ba69ad3daea0f504b07087d3c4d9d4d00000053000000504b01021400140008080800229344587d3c4d9d4d00000053000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000820000000000',FALSE,'2024-02-04 18:25:04.983000','2024-02-04 18:25:04.983000',31,31) +INSERT INTO MINDMAP VALUES(54,'Welcome foo first name','','504b03041400080808002293445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080022934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:05.635000','2024-02-04 18:25:05.635000',32,32) +INSERT INTO MINDMAP VALUES(55,'updatePublishState',NULL,'504b03041400080808002293445800000000000000000000000007000000636f6e74656e740dccdb09c0200c40d155240bb8803a43a113a436d4802f622c1dbff9bb1f871b1a4ef7922c1e3d82627f06382dd428c2145e0d52d03139bb4c5d05ab21d964863e8db0e78d4ac7be2aaf72aa35f814bc4dd30f504b070835ba72bf530000005a000000504b010214001400080808002293445835ba72bf530000005a000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000880000000000',TRUE,'2024-02-04 18:25:05.964000','2024-02-04 18:25:05.964000',32,32) +INSERT INTO MINDMAP VALUES(56,'Welcome foo first name','','504b03041400080808002393445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080023934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:06.848000','2024-02-04 18:25:06.848000',33,33) +INSERT INTO MINDMAP VALUES(57,'Map for Collaboration',NULL,'504b03041400080808002393445800000000000000000000000007000000636f6e74656e740dccc10d80200c40d1559a2ec002c0c5b343545295042829d538bebdbfff63a7092febaa32121a8d4b10ece6ce09a7d6d5314793590b141ea6d41ce9c36ef8b384bbd7a7286cd21a1da264fec19063f06ffe01504b07086d0c1dcc530000005d000000504b01021400140008080800239344586d0c1dcc530000005d000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000880000000000',FALSE,'2024-02-04 18:25:07.171000','2024-02-04 18:25:07.171000',33,33) +INSERT INTO MINDMAP VALUES(58,'Welcome foo first name','','504b03041400080808002393445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080023934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:07.943000','2024-02-04 18:25:07.943000',34,34) +INSERT INTO MINDMAP VALUES(59,'deleteCollabsWithInvalidEmail',NULL,'504b03041400080808002493445800000000000000000000000007000000636f6e74656e740dccbb0d80300c05c055222fc002491a44c104d4069ec092f3516210e393fe743e71752f5a97920319e7ab90b31b09816a939e287a2b550e77205b631da83d18069f053aa130cc4595f7be89dd6b7e59e55c128bd214fd34fef803504b07083292f7c95b00000065000000504b01021400140008080800249344583292f7c95b00000065000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000900000000000',FALSE,'2024-02-04 18:25:08.279000','2024-02-04 18:25:08.279000',34,34) +INSERT INTO MINDMAP VALUES(60,'Welcome foo first name','','504b03041400080808002493445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080024934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:09.231000','2024-02-04 18:25:09.231000',35,35) +INSERT INTO MINDMAP VALUES(61,'new title for map','updated map description','504b03041400080808002493445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080024934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',FALSE,'2024-02-04 18:25:09.584000','2024-02-04 18:25:09.895000',35,35) +INSERT INTO MINDMAP VALUES(62,'Welcome foo first name','','504b03041400080808002593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080025934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:10.527000','2024-02-04 18:25:10.527000',36,36) +INSERT INTO MINDMAP VALUES(63,'Welcome foo first name','','504b03041400080808002593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080025934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:11.560000','2024-02-04 18:25:11.560000',37,37) +INSERT INTO MINDMAP VALUES(64,'Welcome foo first name','','504b03041400080808002693445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080026934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:12.829000','2024-02-04 18:25:12.829000',38,38) +INSERT INTO MINDMAP VALUES(65,'Welcome foo first name','','504b03041400080808002693445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080026934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:13.853000','2024-02-04 18:25:13.853000',39,39) +INSERT INTO MINDMAP VALUES(66,'Welcome foo first name','','504b03041400080808002793445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080027934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:15.336000','2024-02-04 18:25:15.336000',40,40) +INSERT INTO LABEL VALUES(0,'removeLabelFromMindmap',10,NULL,'red') +INSERT INTO LABEL VALUES(1,'Label 1 - ',30,NULL,'COLOR') +INSERT INTO LABEL VALUES(3,'Label 1 - ',40,NULL,'#000000') +INSERT INTO LABEL VALUES(4,'Label 2 - ',40,NULL,'#000000') +INSERT INTO R_LABEL_MINDMAP VALUES(50,1) +INSERT INTO MINDMAP_HISTORY VALUES(0,'504b03041400080808001193445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080011934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',9,'2024-02-04 18:24:34.773000',8) +INSERT INTO MINDMAP_HISTORY VALUES(1,'504b03041400080808001493445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080014934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',17,'2024-02-04 18:24:40.457000',13) +INSERT INTO MINDMAP_HISTORY VALUES(2,'504b03041400080808001993445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a2c43c858adc1c85927ca078718942516a596a5189427246625e7a6ab142716a51596672aaba9d8d3ec80000504b070851cb12a34300000046000000504b010214001400080808001993445851cb12a34300000046000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000780000000000',35,'2024-02-04 18:24:51.508000',23) +INSERT INTO MINDMAP_HISTORY VALUES(3,'504b03041400080808001993445800000000000000000000000007000000636f6e74656e7415cc410e80200c04c0afec8da31f40fe025243134b0d6e94e7abc99c275a3e53ec5e0594c935b0e9854fee9876e051369857dd75cb54efa0a30886dc322835a4b8fcc50b504b0708647aca3f4400000048000000504b0102140014000808080019934458647aca3f4400000048000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000790000000000',35,'2024-02-04 18:24:51.820000',23) +INSERT INTO MINDMAP_HISTORY VALUES(4,'504b03041400080808001993445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a2c43c858adc1c85927ca078718942516a596a5189427246625e7a6ab142716a51596672aaba9d8d3ec80000504b070851cb12a34300000046000000504b010214001400080808001993445851cb12a34300000046000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000780000000000',35,'2024-02-04 18:24:53.099000',23) +INSERT INTO MINDMAP_HISTORY VALUES(5,'504b03041400080808001b93445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b010214001400080808001b934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',39,'2024-02-04 18:24:55.607000',25) +INSERT INTO MINDMAP_HISTORY VALUES(6,'504b03041400080808002493445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080024934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',61,'2024-02-04 18:25:09.896000',35) +INSERT INTO COLLABORATION_PROPERTIES VALUES(0,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(1,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(2,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(3,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(4,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(5,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(8,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(9,FALSE,'{zoom:x}') +INSERT INTO COLLABORATION_PROPERTIES VALUES(10,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(11,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(12,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(13,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(14,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(15,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(16,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(17,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(18,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(19,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(20,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(21,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(22,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(23,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(24,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(25,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(26,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(28,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(32,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(34,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(35,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(36,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(37,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(38,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(39,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(40,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(41,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(42,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(43,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(44,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(45,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(47,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(48,TRUE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(49,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(50,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(51,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(52,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(53,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(55,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(56,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(57,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(58,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(59,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(60,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(61,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(62,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(63,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(64,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(65,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(66,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(67,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(68,FALSE,'{zoom:x}') +INSERT INTO COLLABORATION_PROPERTIES VALUES(69,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(70,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(71,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(72,FALSE,NULL) +INSERT INTO COLLABORATION_PROPERTIES VALUES(73,FALSE,NULL) +INSERT INTO COLLABORATION VALUES(0,3,0,0,0) +INSERT INTO COLLABORATION VALUES(1,3,1,1,0) +INSERT INTO COLLABORATION VALUES(2,4,2,2,0) +INSERT INTO COLLABORATION VALUES(3,5,3,3,0) +INSERT INTO COLLABORATION VALUES(4,6,4,4,0) +INSERT INTO COLLABORATION VALUES(5,6,5,5,0) +INSERT INTO COLLABORATION VALUES(8,8,8,8,0) +INSERT INTO COLLABORATION VALUES(9,8,9,9,0) +INSERT INTO COLLABORATION VALUES(10,9,10,10,0) +INSERT INTO COLLABORATION VALUES(11,9,11,11,0) +INSERT INTO COLLABORATION VALUES(12,10,12,12,0) +INSERT INTO COLLABORATION VALUES(13,10,13,13,0) +INSERT INTO COLLABORATION VALUES(14,11,14,14,0) +INSERT INTO COLLABORATION VALUES(15,11,15,15,0) +INSERT INTO COLLABORATION VALUES(16,12,16,15,1) +INSERT INTO COLLABORATION VALUES(17,13,17,16,0) +INSERT INTO COLLABORATION VALUES(18,13,18,17,0) +INSERT INTO COLLABORATION VALUES(19,14,19,18,0) +INSERT INTO COLLABORATION VALUES(20,14,20,19,0) +INSERT INTO COLLABORATION VALUES(21,15,21,20,0) +INSERT INTO COLLABORATION VALUES(22,15,22,21,0) +INSERT INTO COLLABORATION VALUES(23,16,23,22,0) +INSERT INTO COLLABORATION VALUES(24,16,24,21,1) +INSERT INTO COLLABORATION VALUES(25,17,25,23,0) +INSERT INTO COLLABORATION VALUES(26,17,26,24,0) +INSERT INTO COLLABORATION VALUES(28,18,28,24,1) +INSERT INTO COLLABORATION VALUES(32,20,32,28,0) +INSERT INTO COLLABORATION VALUES(34,21,34,30,0) +INSERT INTO COLLABORATION VALUES(35,21,35,31,0) +INSERT INTO COLLABORATION VALUES(36,22,36,32,0) +INSERT INTO COLLABORATION VALUES(37,22,37,33,0) +INSERT INTO COLLABORATION VALUES(38,23,38,34,0) +INSERT INTO COLLABORATION VALUES(39,23,39,35,0) +INSERT INTO COLLABORATION VALUES(40,24,40,36,0) +INSERT INTO COLLABORATION VALUES(41,24,41,37,0) +INSERT INTO COLLABORATION VALUES(42,25,42,38,0) +INSERT INTO COLLABORATION VALUES(43,25,43,39,0) +INSERT INTO COLLABORATION VALUES(44,26,44,40,0) +INSERT INTO COLLABORATION VALUES(45,26,45,41,0) +INSERT INTO COLLABORATION VALUES(47,27,47,42,0) +INSERT INTO COLLABORATION VALUES(48,27,48,43,0) +INSERT INTO COLLABORATION VALUES(49,28,49,44,0) +INSERT INTO COLLABORATION VALUES(50,28,50,45,0) +INSERT INTO COLLABORATION VALUES(51,28,51,46,0) +INSERT INTO COLLABORATION VALUES(52,29,52,47,0) +INSERT INTO COLLABORATION VALUES(53,29,53,48,0) +INSERT INTO COLLABORATION VALUES(55,12,55,48,2) +INSERT INTO COLLABORATION VALUES(56,30,56,49,0) +INSERT INTO COLLABORATION VALUES(57,30,57,50,0) +INSERT INTO COLLABORATION VALUES(58,31,58,51,0) +INSERT INTO COLLABORATION VALUES(59,31,59,52,0) +INSERT INTO COLLABORATION VALUES(60,31,60,53,0) +INSERT INTO COLLABORATION VALUES(61,32,61,54,0) +INSERT INTO COLLABORATION VALUES(62,32,62,55,0) +INSERT INTO COLLABORATION VALUES(63,33,63,56,0) +INSERT INTO COLLABORATION VALUES(64,33,64,57,0) +INSERT INTO COLLABORATION VALUES(65,34,65,58,0) +INSERT INTO COLLABORATION VALUES(66,34,66,59,0) +INSERT INTO COLLABORATION VALUES(67,35,67,60,0) +INSERT INTO COLLABORATION VALUES(68,35,68,61,0) +INSERT INTO COLLABORATION VALUES(69,36,69,62,0) +INSERT INTO COLLABORATION VALUES(70,37,70,63,0) +INSERT INTO COLLABORATION VALUES(71,38,71,64,0) +INSERT INTO COLLABORATION VALUES(72,39,72,65,0) +INSERT INTO COLLABORATION VALUES(73,40,73,66,0) diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index 39fe85ba..4b457e4e 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -32,6 +32,7 @@ public class RestAppConfig { .securityMatcher("/**") .authorizeHttpRequests(auth -> auth .requestMatchers(mvc.pattern("/api/restfull/users/")).permitAll() + .requestMatchers(mvc.pattern("/api/restfull/authenticate")).permitAll() .requestMatchers(mvc.pattern("/api/restfull/users/resetPassword")).permitAll() .requestMatchers(mvc.pattern("/api/restfull/oauth2/googlecallback")).permitAll() .requestMatchers(mvc.pattern("/api/restfull/oauth2/confirmaccountsync")).permitAll() diff --git a/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java new file mode 100644 index 00000000..363b3b9a --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java @@ -0,0 +1,75 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.wisemapping.rest; + +import com.wisemapping.rest.model.RestJwtUser; +import com.wisemapping.security.JwtTokenUtil; +import com.wisemapping.security.UserDetailsService; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@CrossOrigin +@RequestMapping("/api/restfull") +public class JwtAuthController { + + @Autowired + private AuthenticationManager authenticationManager; + + @Autowired + private UserDetailsService userDetailsService; + + @Autowired + private JwtTokenUtil jwtTokenUtil; + + @RequestMapping(value = "/authenticate", method = RequestMethod.POST) + public ResponseEntity createAuthenticationToken(@RequestBody RestJwtUser user) throws Exception { + + // Is a valid user ? + authenticate(user.getUsername(), user.getPassword()); + + // Create token ... + final UserDetails userDetails = userDetailsService + .loadUserByUsername(user.getUsername()); + + final String token = jwtTokenUtil.generateJwtToken(userDetails); + return ResponseEntity.ok(token); + } + + private void authenticate(@NotNull String username, @NotNull String password) throws Exception { + try { + authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); + } catch (DisabledException e) { + throw new Exception("USER_DISABLED", e); + } catch (BadCredentialsException e) { + throw new Exception("INVALID_CREDENTIALS", e); + } + } +} \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/rest/model/RestJwtUser.java b/wise-api/src/main/java/com/wisemapping/rest/model/RestJwtUser.java new file mode 100644 index 00000000..0eb10aa1 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/rest/model/RestJwtUser.java @@ -0,0 +1,60 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.wisemapping.rest.model; + + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import org.jetbrains.annotations.NotNull; + + +@JsonAutoDetect( + fieldVisibility = JsonAutoDetect.Visibility.NONE, + getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY, + isGetterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY) +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class RestJwtUser { + + private String username; + private String password; + + + public RestJwtUser(@NotNull String username, @NotNull String password) { + this.setUsername(username); + this.setPassword(password); + } + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java new file mode 100644 index 00000000..6f752bed --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java @@ -0,0 +1,61 @@ +package com.wisemapping.security; + +import io.jsonwebtoken.*; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import java.io.Serializable; +import java.security.Key; +import java.util.Date; + +@Component +public class JwtTokenUtil implements Serializable { + final private Logger logger = LogManager.getLogger(); + + @Value("${app.jwt.secret}") + private String jwtSecret; + + @Value("${app.jwt.expirationMs}") + private int jwtExpirationMs; + + public String generateJwtToken(@NotNull final UserDetails user) { + return Jwts.builder() + .setSubject((user.getUsername())) + .setIssuedAt(new Date()) + .setExpiration(new Date((new Date()).getTime() + jwtExpirationMs)) + .signWith(key(), SignatureAlgorithm.HS256) + .compact(); + } + + private Key key() { + return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret)); + } + + public String getUserNameFromJwtToken(String token) { + return Jwts.parserBuilder().setSigningKey(key()).build() + .parseClaimsJws(token).getBody().getSubject(); + } + + public boolean validateJwtToken(String authToken) { + try { + Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken); + return true; + } catch (MalformedJwtException e) { + logger.error("Invalid JWT token: {}", e.getMessage()); + } catch (ExpiredJwtException e) { + logger.error("JWT token is expired: {}", e.getMessage()); + } catch (UnsupportedJwtException e) { + logger.error("JWT token is unsupported: {}", e.getMessage()); + } catch (IllegalArgumentException e) { + logger.error("JWT claims string is empty: {}", e.getMessage()); + } + + return false; + } +} \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/security/UserDetailsService.java b/wise-api/src/main/java/com/wisemapping/security/UserDetailsService.java index e6d04030..246949e2 100644 --- a/wise-api/src/main/java/com/wisemapping/security/UserDetailsService.java +++ b/wise-api/src/main/java/com/wisemapping/security/UserDetailsService.java @@ -36,7 +36,7 @@ public class UserDetailsService @Autowired private UserService userService; - @Value("${admin.user}") + @Value("${app.admin.user}") private String adminUser; @Override diff --git a/wise-api/src/main/java/com/wisemapping/service/MindmapServiceImpl.java b/wise-api/src/main/java/com/wisemapping/service/MindmapServiceImpl.java index e7729265..efc8c71b 100755 --- a/wise-api/src/main/java/com/wisemapping/service/MindmapServiceImpl.java +++ b/wise-api/src/main/java/com/wisemapping/service/MindmapServiceImpl.java @@ -54,7 +54,7 @@ public class MindmapServiceImpl @Autowired private NotificationService notificationService; - @Value("${admin.user}") + @Value("${app.admin.user}") private String adminUser; final private LockManager lockManager; diff --git a/wise-api/src/main/resources/application.yml b/wise-api/src/main/resources/application.yml index 23dde817..be59037e 100755 --- a/wise-api/src/main/resources/application.yml +++ b/wise-api/src/main/resources/application.yml @@ -31,11 +31,13 @@ spring: # Application Configuration. -admin: - user: admin@wisemapping.org -database: - base: - url: /Users/veigap/ +app: + jwt: + secret: dlqxKAg685SaKhsQXIMeM=JWCw3bkl3Ei3Tb7LMlnd19oMd66burPNlJ0Po1qguyjgpakQTk2CN3 + expirationMs: 10000 + admin: + user: admin@wisemapping.org + google: ads: enabled: false diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java new file mode 100644 index 00000000..3f4b45c2 --- /dev/null +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java @@ -0,0 +1,98 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.wisemapping.test.rest; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.wisemapping.config.common.CommonConfig; +import com.wisemapping.config.rest.RestAppConfig; +import com.wisemapping.model.User; +import com.wisemapping.rest.JwtAuthController; +import com.wisemapping.rest.model.RestJwtUser; +import com.wisemapping.rest.model.RestUser; +import com.wisemapping.rest.model.RestUserRegistration; +import com.wisemapping.service.UserService; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import static com.wisemapping.test.rest.RestHelper.createDummyUser; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, JwtAuthController.class}) +@AutoConfigureMockMvc +public class RestJwtAuthControllerTest { + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private UserService userService; + + @Test + void generateTockenValidUser() throws Exception { + final RestJwtUser user = new RestJwtUser("test@wisemapping.org", "test"); + final String userJson = objectMapper.writeValueAsString(user); + + mockMvc.perform( + post("/api/restfull/authenticate"). + contentType(MediaType.APPLICATION_JSON) + .content(userJson)) + .andExpect(status().isOk()); + } + + @Test + void generateTokenInvalidPassword() throws Exception { + final RestJwtUser user = new RestJwtUser("test@wisemapping.org", "test1"); + final String userJson = objectMapper.writeValueAsString(user); + + mockMvc.perform( + post("/api/restfull/authenticate"). + contentType(MediaType.APPLICATION_JSON) + .content(userJson)) + .andExpect(status().is4xxClientError()); + } + + @Test + void generateTokenInvalidPasswordUser() throws Exception { + final RestJwtUser user = new RestJwtUser("test-not-exist@wisemapping.org", "test"); + final String userJson = objectMapper.writeValueAsString(user); + + mockMvc.perform( + post("/api/restfull/authenticate"). + contentType(MediaType.APPLICATION_JSON) + .content(userJson)) + .andExpect(status().is4xxClientError()); + } + +} From 082f2614e393c372ba1a4401617bf4c3faab44af Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 19:45:14 -0800 Subject: [PATCH 057/110] Move to in memory --- .../db/wisemapping.properties | 5 - .../db/wisemapping.script | 344 ------------------ .../config/rest/RestAppConfig.java | 8 + .../filter/JwtAuthenticationFilter.java | 64 ++++ .../wisemapping/rest/JwtAuthController.java | 8 +- .../wisemapping/security/JwtTokenUtil.java | 4 +- wise-api/src/main/resources/application.yml | 2 +- .../test/rest/RestJwtAuthControllerTest.java | 19 +- 8 files changed, 97 insertions(+), 357 deletions(-) delete mode 100644 wise-api/${database.base.url}/db/wisemapping.properties delete mode 100644 wise-api/${database.base.url}/db/wisemapping.script create mode 100644 wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java diff --git a/wise-api/${database.base.url}/db/wisemapping.properties b/wise-api/${database.base.url}/db/wisemapping.properties deleted file mode 100644 index 6806b69c..00000000 --- a/wise-api/${database.base.url}/db/wisemapping.properties +++ /dev/null @@ -1,5 +0,0 @@ -#HSQL Database Engine 2.7.1 -#Sun Feb 04 18:28:11 PST 2024 -modified=yes -tx_timestamp=992 -version=2.7.1 diff --git a/wise-api/${database.base.url}/db/wisemapping.script b/wise-api/${database.base.url}/db/wisemapping.script deleted file mode 100644 index 8157e5ab..00000000 --- a/wise-api/${database.base.url}/db/wisemapping.script +++ /dev/null @@ -1,344 +0,0 @@ -SET DATABASE UNIQUE NAME HSQLDB8D7714344E -SET DATABASE DEFAULT RESULT MEMORY ROWS 0 -SET DATABASE EVENT LOG LEVEL 0 -SET DATABASE TRANSACTION CONTROL LOCKS -SET DATABASE DEFAULT ISOLATION LEVEL READ COMMITTED -SET DATABASE TRANSACTION ROLLBACK ON CONFLICT TRUE -SET DATABASE TEXT TABLE DEFAULTS '' -SET DATABASE SQL NAMES FALSE -SET DATABASE SQL RESTRICT EXEC FALSE -SET DATABASE SQL REFERENCES FALSE -SET DATABASE SQL SIZE TRUE -SET DATABASE SQL TYPES FALSE -SET DATABASE SQL TDC DELETE TRUE -SET DATABASE SQL TDC UPDATE TRUE -SET DATABASE SQL SYS INDEX NAMES TRUE -SET DATABASE SQL CONCAT NULLS TRUE -SET DATABASE SQL UNIQUE NULLS TRUE -SET DATABASE SQL CONVERT TRUNCATE TRUE -SET DATABASE SQL AVG SCALE 0 -SET DATABASE SQL DOUBLE NAN TRUE -SET DATABASE SQL SYNTAX MYS TRUE -SET FILES WRITE DELAY 500 MILLIS -SET FILES BACKUP INCREMENT TRUE -SET FILES CACHE SIZE 10000 -SET FILES CACHE ROWS 50000 -SET FILES SCALE 32 -SET FILES LOB SCALE 32 -SET FILES DEFRAG 0 -SET FILES NIO TRUE -SET FILES NIO SIZE 256 -SET FILES LOG TRUE -SET FILES LOG SIZE 50 -SET FILES CHECK 992 -SET DATABASE COLLATION "SQL_TEXT" PAD SPACE -CREATE USER SA PASSWORD DIGEST 'd41d8cd98f00b204e9800998ecf8427e' -ALTER USER SA SET LOCAL TRUE -CREATE SCHEMA PUBLIC AUTHORIZATION DBA -CREATE MEMORY TABLE PUBLIC.COLLABORATOR(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,EMAIL VARCHAR(255) NOT NULL,CREATION_DATE DATE,UNIQUE(EMAIL)) -ALTER TABLE PUBLIC.COLLABORATOR ALTER COLUMN ID RESTART WITH 41 -CREATE MEMORY TABLE PUBLIC.USER(COLABORATOR_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,AUTHENTICATION_TYPE CHARACTER(1) NOT NULL,AUTHENTICATOR_URI VARCHAR(255),FIRSTNAME VARCHAR(255) NOT NULL,LASTNAME VARCHAR(255) NOT NULL,PASSWORD VARCHAR(255) NOT NULL,ACTIVATION_CODE BIGINT NOT NULL,ACTIVATION_DATE DATE,ALLOW_SEND_EMAIL CHARACTER(1) NOT NULL,LOCALE VARCHAR(5),GOOGLE_SYNC BOOLEAN,SYNC_CODE VARCHAR(255),GOOGLE_TOKEN VARCHAR(255),FOREIGN KEY(COLABORATOR_ID) REFERENCES PUBLIC.COLLABORATOR(ID)) -ALTER TABLE PUBLIC.USER ALTER COLUMN COLABORATOR_ID RESTART WITH 41 -CREATE MEMORY TABLE PUBLIC.MINDMAP(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,TITLE VARCHAR(255) NOT NULL,DESCRIPTION VARCHAR(255),XML VARBINARY(16777216) NOT NULL,PUBLIC BOOLEAN NOT NULL,CREATION_DATE TIMESTAMP,EDITION_DATE TIMESTAMP,CREATOR_ID INTEGER NOT NULL,LAST_EDITOR_ID INTEGER NOT NULL) -ALTER TABLE PUBLIC.MINDMAP ALTER COLUMN ID RESTART WITH 67 -CREATE MEMORY TABLE PUBLIC.LABEL(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,TITLE VARCHAR(30),CREATOR_ID INTEGER NOT NULL,PARENT_LABEL_ID INTEGER,COLOR VARCHAR(7) NOT NULL) -ALTER TABLE PUBLIC.LABEL ALTER COLUMN ID RESTART WITH 5 -CREATE MEMORY TABLE PUBLIC.R_LABEL_MINDMAP(MINDMAP_ID INTEGER NOT NULL,LABEL_ID INTEGER NOT NULL,PRIMARY KEY(MINDMAP_ID,LABEL_ID),FOREIGN KEY(MINDMAP_ID) REFERENCES PUBLIC.MINDMAP(ID),FOREIGN KEY(LABEL_ID) REFERENCES PUBLIC.LABEL(ID) ON DELETE CASCADE) -CREATE MEMORY TABLE PUBLIC.MINDMAP_HISTORY(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,XML VARBINARY(16777216) NOT NULL,MINDMAP_ID INTEGER NOT NULL,CREATION_DATE TIMESTAMP,EDITOR_ID INTEGER NOT NULL,FOREIGN KEY(MINDMAP_ID) REFERENCES PUBLIC.MINDMAP(ID)) -ALTER TABLE PUBLIC.MINDMAP_HISTORY ALTER COLUMN ID RESTART WITH 7 -CREATE MEMORY TABLE PUBLIC.COLLABORATION_PROPERTIES(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,STARRED BOOLEAN NOT NULL,MINDMAP_PROPERTIES VARCHAR(512)) -ALTER TABLE PUBLIC.COLLABORATION_PROPERTIES ALTER COLUMN ID RESTART WITH 74 -CREATE MEMORY TABLE PUBLIC.COLLABORATION(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,COLABORATOR_ID INTEGER NOT NULL,PROPERTIES_ID INTEGER NOT NULL,MINDMAP_ID INTEGER NOT NULL,ROLE_ID INTEGER NOT NULL,FOREIGN KEY(COLABORATOR_ID) REFERENCES PUBLIC.COLLABORATOR(ID),FOREIGN KEY(MINDMAP_ID) REFERENCES PUBLIC.MINDMAP(ID),FOREIGN KEY(PROPERTIES_ID) REFERENCES PUBLIC.COLLABORATION_PROPERTIES(ID)) -ALTER TABLE PUBLIC.COLLABORATION ALTER COLUMN ID RESTART WITH 74 -CREATE MEMORY TABLE PUBLIC.ACCESS_AUDITORY(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,USER_ID INTEGER NOT NULL,LOGIN_DATE DATE,FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(COLABORATOR_ID) ON DELETE CASCADE) -ALTER TABLE PUBLIC.ACCESS_AUDITORY ALTER COLUMN ID RESTART WITH 0 -ALTER SEQUENCE SYSTEM_LOBS.LOB_ID RESTART WITH 1 -SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CARDINAL_NUMBER TO PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.YES_OR_NO TO PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CHARACTER_DATA TO PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.SQL_IDENTIFIER TO PUBLIC -GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.TIME_STAMP TO PUBLIC -GRANT DBA TO SA -SET SCHEMA SYSTEM_LOBS -INSERT INTO BLOCKS VALUES(0,2147483647,0) -SET SCHEMA PUBLIC -INSERT INTO COLLABORATOR VALUES(1,'test@wisemapping.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(2,'admin@wisemapping.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(3,'foo-to-delete1095503453352583@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(4,'foo-to-delete1095504838563541@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(5,'foo-to-delete1095505168712666@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(6,'foo-to-delete1095505810331125@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(8,'foo-to-delete1095507564789583@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(9,'foo-to-delete1095509185883583@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(10,'foo-to-delete1095510144202500@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(11,'foo-to-delete1095512040923666@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(12,'new-collab@example.com','2024-02-04') -INSERT INTO COLLABORATOR VALUES(13,'foo-to-delete1095513302479041@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(14,'foo-to-delete1095514551101291@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(15,'foo-to-delete1095515506054708@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(16,'foo-to-delete1095516166443791@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(17,'foo-to-delete1095517157929916@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(18,'another-collab@example.com','2024-02-04') -INSERT INTO COLLABORATOR VALUES(19,'foo-to-delete1095519033584291@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(20,'foo-to-delete1095520924763291@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(21,'foo-to-delete1095522170804250@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(22,'foo-to-delete1095523103464166@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(23,'foo-to-delete1095524343860250@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(24,'foo-to-delete1095527193855625@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(25,'foo-to-delete1095528435850666@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(26,'foo-to-delete1095529692935041@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(27,'foo-to-delete1095531562488791@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(28,'foo-to-delete1095532816384416@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(29,'foo-to-delete1095534077960000@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(30,'foo-to-delete1095536060733875@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(31,'foo-to-delete1095537826621458@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(32,'foo-to-delete1095539107013833@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(33,'foo-to-delete1095540287897833@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(34,'foo-to-delete1095541404608166@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(35,'foo-to-delete1095542691628458@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(36,'foo-to-delete1095543993678916@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(37,'foo-to-delete1095545009514416@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(38,'foo-to-delete1095545990485750@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(39,'foo-to-delete1095547256374750@example.org','2024-02-04') -INSERT INTO COLLABORATOR VALUES(40,'foo-to-delete1095548781024250@example.org','2024-02-04') -INSERT INTO USER VALUES(1,'D',NULL,'Test','User','ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3',1237,'2024-02-04','1',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(2,'D',NULL,'Admin','User','ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3',1237,'2024-02-04','1',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(3,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$TX8Pjoa4ulpGuHdlXY5ax.dTQrdhBvbVTWIM3MfpBoO3zBeoplHl6',-4850015659903415425,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(4,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$bLo7xEJuQuoCMTCKYdoINewk4Mm0mzN3SEDk499MUNkLqUB/vA8OW',-8352090659676303034,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(5,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$cv8hHr/zoVlG0HUWKiijv.mKJxTWfsNLL0dHM3THst6p4E7Jgzpw2',-6036910863989637121,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(6,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$gRV7wdtrBnFvn.emYT6CTuJB7GWMGFn2AzXvJUD7acJ5LgKS2oiXi',-8568901134768544702,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(8,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$UZAhmFoGXhCiCkvUNIS4GuZ1uEWjKxZBMzp5TQq0QaYXNKoKw0h/m',-8295815163365799267,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(9,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$AzXTttUaES.gFJSu3.sUQemZDWFTr4T6ioptclM8PlVwDxr8HqniO',-5397813652597351155,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(10,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$W9FUJhA8f70D.7HIbSBva.MepMnChErqNGL8/BXgZZWH07NRnvWL2',-7544650540467244908,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(11,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$ShthGXm75P1q7UjiL6vT3.mxfTqu/gAGdT4ixyaie3dI./HTDRXp6',-7889606868798742570,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(13,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$4/8N2lm7qnFZZMl3emRGj.H94GHNRR/OUeXosXPhoby2XJgD1uDXC',-7268335255585620308,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(14,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$auyw0LUob2ZvQjHnkUPAK.WwSKthFTwMxdmLxsFOBJQw6Rz5eKgjW',-4859760027220123933,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(15,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$mOgC/KvhkICw0HcgSPOx7.AUIb6awLT.jdOMjT41VueeRylA5H.Z2',-8379618723328975557,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(16,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$dGuajA6k/TJ9h/7TgwYheuXkvggOutT4ZwP./Du3FuNdOy5hW20QK',-5844770767303893147,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(17,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$e6aVGr94W/qynvODuk/Wsu.hjH3bsGeR3.TlEkV2oHDrig9fUGpaq',-8583719471462548065,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(19,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$a6ZsOVlI80B3qL1qXIR1C.6bOrZAajfcI.P8QOVDjRfUwyb6kz4Pa',-6844205299178825206,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(20,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$IVnbFIfkP7UGmIx7lP9bAO9udtyjXRTOR.c4eMp.aGyvFG.QdLfhy',-6297938040158171470,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(21,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$3u8r0ruJmhj15HBRhYjRA.6pnme71QosWQujwAFoR6QDrraxxulK6',-5783544984352539928,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(22,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$xOunjQvmPEbQx0HZOmzhvOmdpXEKI2rQZN0yegH8rlMDoK5NX8Qny',-5700156451683586162,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(23,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$mdFPUQ8hcJsu7tCpVKRb4es8wOo/VI1Qo30IfVeQzOcdugeJq3mN.',-7615810263780338939,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(24,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$OwTgW8Cwam.eWhVOJ1FH9./.xiVzCU5iutXaaLkJihkx5L4xOtcxS',-5727811444992568492,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(25,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$9jMjvDrrfCDj.PuFT9IpKeZACRF56sSSP1SwlhL5kLwAC7s7SgvXa',-5793072758750432848,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(26,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$G.6f9UJAtyFd9tSt9LZ0W.v4XH3VpMmUF7zhnICu70fTk5NhEqls2',-9172141193380704830,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(27,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$CI/aeAwL2aiwXMxZaxVGJ.icl2TZqBePLVwZUL/1cqWQK7pINWWE2',-5834501834858404373,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(28,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$Prit/d2Mpo4phHAK0ALumu0oUwRMZyrcP.7D5WSkavQzotB3VYJMi',-5937808155108140865,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(29,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$1jzMy7/E7UwrwK.pVtyIOOHDiH9l8EymcYdGHGBJptRNNpzYCje4q',-9177769807106770742,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(30,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$uTzqaCht0Rph/vws4cUziea6azU78gDUBo1xIGGWZV7BLfi5U.Y.q',-8111317027341093629,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(31,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$Gp2HGMmn3MrfABRsrTJiFe/S.LPQikJhFMse7O.hRTnNvRdeKTBbO',-5277431289150781474,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(32,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$HLkQd4gXaj0EbH/BSKBDMeqK9hVtLuo1HR8/DlN1xkYLFG34R1a9q',-8979411792095495717,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(33,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$8KHuDAkByNzMuMAaXA4tVuJNEyZY6Fi9UwMfEFPxNby0GbvmYZhTG',-6697485127552960846,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(34,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$TtVJlYYIfKMgBoNCgQpPrOEVhBfhE/D7P3NAAsqFc/g9GgiwZMnPa',-8668916251663383176,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(35,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$1ahc8uZFPiPh2XaGejoiweB3asNvRAzlJKokutFBczKTh4/G9rwo6',-5329239724338752792,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(36,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$omerC2OpRJ7QhSMfABXx7OOdpV51QkysVrU0W9Qw2rfOSZmC/z02.',-6023724487699956165,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(37,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$IztIOSJDDJxbDYiAKmEMnuOSSuz6bGQPp5twZeGXQnLmqGZEAqQd.',-5119440034016837315,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(38,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$QiblVCcv.pWfZt0pHgBdLOj1896OHTZG1t0ADubHMgmANS1Smyj0G',-6920785024573180477,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(39,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$Gu0N.1TlBLxZ/guyb4rXeOSJAoGMC19uqczSYbf2nB8elV6VMfdgi',-5776845727120034520,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO USER VALUES(40,'D',NULL,'foo first name','foo last name','{bcrypt}$2a$12$CBmNnCT1y3d9SjX5tuGLROp6ml0GDS1fRaTGTfJ4baCFu.3crS5FO',-8203322937841654308,'2024-02-04','0',NULL,NULL,NULL,NULL) -INSERT INTO MINDMAP VALUES(0,'Welcome foo first name','','504b03041400080808000f93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808000f934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:30.682000','2024-02-04 18:24:30.682000',3,3) -INSERT INTO MINDMAP VALUES(1,'deleteWithoutOwnerPermission',NULL,'504b03041400080808000f93445800000000000000000000000007000000636f6e74656e7415cccb0d80201005c056c8366003400b7af34cf04537e1976551cb17ef93b1393473433ad7e24843392b19bd90e1a809f74cde6a6d1c4d4451096922199806af3a3a90a0d859af3a747d0a648364ee7f478bb7cbecfd07504b0708c6e2041f5700000064000000504b010214001400080808000f934458c6e2041f5700000064000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008c0000000000',FALSE,'2024-02-04 18:24:31.049000','2024-02-04 18:24:31.049000',3,3) -INSERT INTO MINDMAP VALUES(2,'Welcome foo first name','','504b03041400080808000f93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808000f934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:31.378000','2024-02-04 18:24:31.378000',4,4) -INSERT INTO MINDMAP VALUES(3,'Welcome foo first name','','504b03041400080808000f93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808000f934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:31.700000','2024-02-04 18:24:31.700000',5,5) -INSERT INTO MINDMAP VALUES(4,'Welcome foo first name','','504b03041400080808001093445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080010934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:32.357000','2024-02-04 18:24:32.357000',6,6) -INSERT INTO MINDMAP VALUES(5,'verifyMapOwnership Map user 1',NULL,'504b03041400080808001093445800000000000000000000000007000000636f6e74656e740d8cdb0980300c0057095940fc6fbb813843295103b60d697c6d6f3e0fee2ed42c70930eee2da2e5b677043ba85244511e1553b02e5ca05033cda74b7a913bf45a442f79fb962cebd37c72b080035c8314669c5298fc9f7e504b07085f0580fb5800000065000000504b01021400140008080800109344585f0580fb5800000065000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008d0000000000',FALSE,'2024-02-04 18:24:32.713000','2024-02-04 18:24:32.713000',6,6) -INSERT INTO MINDMAP VALUES(8,'Welcome foo first name','','504b03041400080808001193445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080011934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:34.105000','2024-02-04 18:24:34.105000',8,8) -INSERT INTO MINDMAP VALUES(9,'Update sample ',NULL,'504b03041400080808001193445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080011934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',FALSE,'2024-02-04 18:24:34.449000','2024-02-04 18:24:34.768000',8,8) -INSERT INTO MINDMAP VALUES(10,'Welcome foo first name','','504b03041400080808001193445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080011934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:35.719000','2024-02-04 18:24:35.719000',9,9) -INSERT INTO MINDMAP VALUES(11,'addCollabWhitOwnerRole',NULL,'504b03041400080808001293445800000000000000000000000007000000636f6e74656e740dcccb0d80200c00d05548177001e0e200265e3c576884042829f533bedc5f9eadd8cd43323237078aed62309aa892832e7954f056b9e7600235152c13c94dd3d0a70e30c6954bc1f34859b7b791ec5c08166f9719fb1f504b0708d1486f3d570000005e000000504b0102140014000808080012934458d1486f3d570000005e000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008c0000000000',FALSE,'2024-02-04 18:24:36.046000','2024-02-04 18:24:36.046000',9,9) -INSERT INTO MINDMAP VALUES(12,'Welcome foo first name','','504b03041400080808001293445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080012934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:36.681000','2024-02-04 18:24:36.681000',10,10) -INSERT INTO MINDMAP VALUES(13,'removeLabelFromMindmap',NULL,'504b03041400080808001293445800000000000000000000000007000000636f6e74656e740dccc10d80200c46e15548177001e0e8498740fca3249492528de3cbe95dbe3ccfa9bb173a8ab44096da25e4ec062350d73298a237e925bb8c669aea44fa601a7c1648c1f2624b07eaaac27b69e71cd212fd321b7f504b070811bf9114550000005e000000504b010214001400080808001293445811bf9114550000005e000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008a0000000000',FALSE,'2024-02-04 18:24:37.317000','2024-02-04 18:24:37.317000',10,10) -INSERT INTO MINDMAP VALUES(14,'Welcome foo first name','','504b03041400080808001393445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080013934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:38.576000','2024-02-04 18:24:38.576000',11,11) -INSERT INTO MINDMAP VALUES(15,'Map for addCollabs - ',NULL,'504b03041400080808001393445800000000000000000000000007000000636f6e74656e740dccc10d80200c40d1559ade0d0b0017cf0e51b12a095052aa717cb9bfff7da50e2febc8d2021ab54b10ece6ca01bbe651317a939e13246ea65426d287a7e1cf026eb33e45818e639552681f000ba08bdecd71fc01504b07085e2e2812550000005e000000504b01021400140008080800139344585e2e2812550000005e000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008a0000000000',FALSE,'2024-02-04 18:24:38.897000','2024-02-04 18:24:38.897000',11,11) -INSERT INTO MINDMAP VALUES(16,'Welcome foo first name','','504b03041400080808001393445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080013934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:39.830000','2024-02-04 18:24:39.830000',13,13) -INSERT INTO MINDMAP VALUES(17,'Update XML sample',NULL,'504b03041400080808001493445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080014934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',FALSE,'2024-02-04 18:24:40.146000','2024-02-04 18:24:40.456000',13,13) -INSERT INTO MINDMAP VALUES(18,'Welcome foo first name','','504b03041400080808001493445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080014934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:41.102000','2024-02-04 18:24:41.102000',14,14) -INSERT INTO MINDMAP VALUES(19,'Map for deleteOwnerCollab',NULL,'504b03041400080808001493445800000000000000000000000007000000636f6e74656e740dcccb0d80201045d156c8346003c0c6b5b106c4a792004386f153beeccfbdb684661e484f5c1d69a82793d10b058e9aa45ec85be596a289a82a210f243786c1a78e96511f2c664786627d2b64e69cc34693b7d378fb1f504b0708950dc3915700000061000000504b0102140014000808080014934458950dc3915700000061000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008c0000000000',FALSE,'2024-02-04 18:24:41.414000','2024-02-04 18:24:41.414000',14,14) -INSERT INTO MINDMAP VALUES(20,'Welcome foo first name','','504b03041400080808001593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080015934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:42.033000','2024-02-04 18:24:42.033000',15,15) -INSERT INTO MINDMAP VALUES(21,'MaddCollabWhitoutOwnerPermission',NULL,'504b03041400080808001593445800000000000000000000000007000000636f6e74656e7415cd310ec3200c40d1ab205f20170096ce55b3657689152c0146c6b43d7ee8fef4bfafd8dd8774b0b40086ed127096a95280ae3c2a446fd239b944cd14cb423a6919fa5980279ee7434ac1f791d964daebdb4877d2cae39f842dfa6d2de20d504b0708951b63065f00000068000000504b0102140014000808080015934458951b63065f00000068000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000940000000000',FALSE,'2024-02-04 18:24:42.364000','2024-02-04 18:24:42.364000',15,15) -INSERT INTO MINDMAP VALUES(22,'Welcome foo first name','','504b03041400080808001593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080015934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:42.755000','2024-02-04 18:24:42.755000',16,16) -INSERT INTO MINDMAP VALUES(23,'Welcome foo first name','','504b03041400080808001593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080015934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:43.695000','2024-02-04 18:24:43.695000',17,17) -INSERT INTO MINDMAP VALUES(24,'Map for updateCollabs',NULL,'504b03041400080808001693445800000000000000000000000007000000636f6e74656e740dccc10d80200c40d15548176001e0e2d9212a5625014a4a318e6fefefffd070b8976416ee1114fbcde0f4a146118694d92005e551b2cbd455b01a924566e8d308bbd5178b5be344a58d6bc563824fc1db37fd504b07082f650996530000005d000000504b01021400140008080800169344582f650996530000005d000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000880000000000',FALSE,'2024-02-04 18:24:44.008000','2024-02-04 18:24:44.008000',17,17) -INSERT INTO MINDMAP VALUES(28,'Welcome foo first name','','504b03041400080808001793445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080017934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:47.456000','2024-02-04 18:24:47.456000',20,20) -INSERT INTO MINDMAP VALUES(30,'Welcome foo first name','','504b03041400080808001893445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080018934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:48.698000','2024-02-04 18:24:48.698000',21,21) -INSERT INTO MINDMAP VALUES(31,'Map to Validate Creation',NULL,'504b03041400080808001893445800000000000000000000000007000000636f6e74656e740dccbb0d80300c00d1552c2f90059234d4b4f456b0c0527e720c627cdcbfbbd868c2cbba64f48446fd1a087673e384536535ccd1c6940285bb295547fab01bfe2ce1eeb50d38a8ca49c6b02993f90a438ec1d7f907504b0708d90b4c985500000060000000504b0102140014000808080018934458d90b4c985500000060000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008a0000000000',FALSE,'2024-02-04 18:24:49.012000','2024-02-04 18:24:49.012000',21,21) -INSERT INTO MINDMAP VALUES(32,'Welcome foo first name','','504b03041400080808001893445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080018934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:49.631000','2024-02-04 18:24:49.631000',22,22) -INSERT INTO MINDMAP VALUES(33,'New map to change title - application/json',NULL,'504b03041400080808001893445800000000000000000000000007000000636f6e74656e740dccd109c0200c45d1554216700175830e2112aaa046e26be9f8cdff3d37ceb2e9153b5d576294752b139a4c49bcad9fc9394277af5465c1caf0c81ef1463e24be5c43a9368742e818c221c7e0d7fc03504b07080bfb1a9e500000005b000000504b01021400140008080800189344580bfb1a9e500000005b000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000850000000000',FALSE,'2024-02-04 18:24:49.941000','2024-02-04 18:24:49.941000',22,22) -INSERT INTO MINDMAP VALUES(34,'Welcome foo first name','','504b03041400080808001993445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080019934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:50.882000','2024-02-04 18:24:50.882000',23,23) -INSERT INTO MINDMAP VALUES(35,'map to test revert changes',NULL,'504b03041400080808001993445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a2c43c858adc1c85927ca078718942516a596a5189427246625e7a6ab142716a51596672aaba9d8d3ec80000504b070851cb12a34300000046000000504b010214001400080808001993445851cb12a34300000046000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000780000000000',FALSE,'2024-02-04 18:24:51.195000','2024-02-04 18:24:52.481000',23,23) -INSERT INTO MINDMAP VALUES(36,'Welcome foo first name','','504b03041400080808001a93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001a934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:53.724000','2024-02-04 18:24:53.724000',24,24) -INSERT INTO MINDMAP VALUES(37,'Map to change Description ','New map to change description ','504b03041400080808001b93445800000000000000000000000007000000636f6e74656e740dccc10dc0200840d155080bb8807aeab5431842aa491582b4e9f8e5fedfcfb329bc6c7bc82ae86d5d82e09d2717541b7b62cd2e3a0888975bbb23b287a3e1cf0b9ea15d807a40868337d9508f1760aa39c5bcfe504b07087246c8a85400000062000000504b010214001400080808001b9344587246c8a85400000062000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000890000000000',FALSE,'2024-02-04 18:24:54.041000','2024-02-04 18:24:54.041000',24,24) -INSERT INTO MINDMAP VALUES(38,'Welcome foo first name','','504b03041400080808001b93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001b934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:54.970000','2024-02-04 18:24:54.970000',25,25) -INSERT INTO MINDMAP VALUES(39,'Map to change title',NULL,'504b03041400080808001b93445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b010214001400080808001b934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',FALSE,'2024-02-04 18:24:55.289000','2024-02-04 18:24:55.606000',25,25) -INSERT INTO MINDMAP VALUES(40,'Welcome foo first name','','504b03041400080808001c93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001c934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:56.221000','2024-02-04 18:24:56.221000',26,26) -INSERT INTO MINDMAP VALUES(41,'Map for deleteCollabs - ',NULL,'504b03041400080808001c93445800000000000000000000000007000000636f6e74656e740dcc410e80200c05d1ab34dd1b2f006c5c7b08d4af920025a51a8f2ffb37e34a6cf4427b92ead962bd84c96e14786e9a7ae1e04c5ada6947358d79207d300c3ef3bc8efa14a503198645728e5b279a88e7e0e6f10e3f504b070860b5a1da5600000061000000504b010214001400080808001c93445860b5a1da5600000061000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008b0000000000',FALSE,'2024-02-04 18:24:56.534000','2024-02-04 18:24:56.534000',26,26) -INSERT INTO MINDMAP VALUES(42,'Welcome foo first name','','504b03041400080808001d93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001d934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:58.091000','2024-02-04 18:24:58.091000',27,27) -INSERT INTO MINDMAP VALUES(43,'Stared Map user 1',NULL,'504b03041400080808001d93445800000000000000000000000007000000636f6e74656e740dcccd0d80200c06d0559a2e40bc031b78728206bf2889fca414e3f8727f79be48a7173a72ab814dead598ec4641e0ae79148ede5acf8912aaa93c0be9c432f82cf061a238695fc91c50dad845efd6197f504b0708cc8a306c5100000059000000504b010214001400080808001d934458cc8a306c5100000059000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000860000000000',FALSE,'2024-02-04 18:24:58.402000','2024-02-04 18:24:58.402000',27,27) -INSERT INTO MINDMAP VALUES(44,'Welcome foo first name','','504b03041400080808001d93445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b010214001400080808001d934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:24:59.351000','2024-02-04 18:24:59.351000',28,28) -INSERT INTO MINDMAP VALUES(45,'Map to clone sample ',NULL,'504b03041400080808001d93445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a24485e49cfcbcd41405a002753b1b7d903a00504b070843b305852a0000002d000000504b010214001400080808001d93445843b305852a0000002d000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005f0000000000',FALSE,'2024-02-04 18:24:59.661000','2024-02-04 18:24:59.661000',28,28) -INSERT INTO MINDMAP VALUES(46,'Cloned map but with previous content.','Cloned map desc','504b03041400080808001d93445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a24485e49cfcbcd41405a002753b1b7d903a00504b070843b305852a0000002d000000504b010214001400080808001d93445843b305852a0000002d000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005f0000000000',FALSE,'2024-02-04 18:24:59.983000','2024-02-04 18:24:59.983000',28,28) -INSERT INTO MINDMAP VALUES(47,'Welcome foo first name','','504b03041400080808002093445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080020934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:00.609000','2024-02-04 18:25:00.609000',29,29) -INSERT INTO MINDMAP VALUES(48,'Map for updateCollabType',NULL,'504b03041400080808002093445800000000000000000000000007000000636f6e74656e740dccc10d80200c40d15548176001e0e2d99b0b54ad4a02b4a9c5e8f6727fff878ae21ed23b738b60d84e066717558a209aef0a29184bdedc46cd14cb40da69187a2dc23cea83d575d9d168e252705d3e21f029f8b14e3f504b07081154cf865700000060000000504b01021400140008080800209344581154cf865700000060000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000008c0000000000',FALSE,'2024-02-04 18:25:00.932000','2024-02-04 18:25:00.932000',29,29) -INSERT INTO MINDMAP VALUES(49,'Welcome foo first name','','504b03041400080808002193445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080021934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:02.656000','2024-02-04 18:25:02.656000',30,30) -INSERT INTO MINDMAP VALUES(50,'Maps 1 - ',NULL,'504b03041400080808002193445800000000000000000000000007000000636f6e74656e740dccc109c0200c05d0553eb917e95ddda0430409ad5035c4b474fc7a7fbcd858f18acd3a7a22e77e0e825fd224915a9d8d72f4a1b5a04877e37b217b6419f93cd1c13ab1031b28e41856967f504b070886439d2e4c00000052000000504b010214001400080808002193445886439d2e4c00000052000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000810000000000',FALSE,'2024-02-04 18:25:03.353000','2024-02-04 18:25:03.353000',30,30) -INSERT INTO MINDMAP VALUES(51,'Welcome foo first name','','504b03041400080808002293445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080022934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:04.361000','2024-02-04 18:25:04.361000',31,31) -INSERT INTO MINDMAP VALUES(52,'List Maps 1',NULL,'504b03041400080808002293445800000000000000000000000007000000636f6e74656e740dccc10980300c00c055421628fedb4ea04384123460db9044717cfb3f2e775278d95ce6281834ce891017772ea826deb1e6982a0d1a8f30ba17b28797e12f0aeee20107a9c386a9e6b4b6fa03504b07087e877a764d00000053000000504b01021400140008080800229344587e877a764d00000053000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000820000000000',FALSE,'2024-02-04 18:25:04.675000','2024-02-04 18:25:04.675000',31,31) -INSERT INTO MINDMAP VALUES(53,'List Maps 2',NULL,'504b03041400080808002293445800000000000000000000000007000000636f6e74656e740dccc10980300c00c055421628f86e3b810e114ad0806d4312c5f1edffb8dc49e1657399a360d03827425cdcb9a09a78c79a63aa34683cc2e85ec81e5e86bf28b88b071ca40e1ba69ad3daea0f504b07087d3c4d9d4d00000053000000504b01021400140008080800229344587d3c4d9d4d00000053000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000820000000000',FALSE,'2024-02-04 18:25:04.983000','2024-02-04 18:25:04.983000',31,31) -INSERT INTO MINDMAP VALUES(54,'Welcome foo first name','','504b03041400080808002293445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080022934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:05.635000','2024-02-04 18:25:05.635000',32,32) -INSERT INTO MINDMAP VALUES(55,'updatePublishState',NULL,'504b03041400080808002293445800000000000000000000000007000000636f6e74656e740dccdb09c0200c40d155240bb8803a43a113a436d4802f622c1dbff9bb1f871b1a4ef7922c1e3d82627f06382dd428c2145e0d52d03139bb4c5d05ab21d964863e8db0e78d4ac7be2aaf72aa35f814bc4dd30f504b070835ba72bf530000005a000000504b010214001400080808002293445835ba72bf530000005a000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000880000000000',TRUE,'2024-02-04 18:25:05.964000','2024-02-04 18:25:05.964000',32,32) -INSERT INTO MINDMAP VALUES(56,'Welcome foo first name','','504b03041400080808002393445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080023934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:06.848000','2024-02-04 18:25:06.848000',33,33) -INSERT INTO MINDMAP VALUES(57,'Map for Collaboration',NULL,'504b03041400080808002393445800000000000000000000000007000000636f6e74656e740dccc10d80200c40d1559a2ec002c0c5b343545295042829d538bebdbfff63a7092febaa32121a8d4b10ece6ce09a7d6d5314793590b141ea6d41ce9c36ef8b384bbd7a7286cd21a1da264fec19063f06ffe01504b07086d0c1dcc530000005d000000504b01021400140008080800239344586d0c1dcc530000005d000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000880000000000',FALSE,'2024-02-04 18:25:07.171000','2024-02-04 18:25:07.171000',33,33) -INSERT INTO MINDMAP VALUES(58,'Welcome foo first name','','504b03041400080808002393445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080023934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:07.943000','2024-02-04 18:25:07.943000',34,34) -INSERT INTO MINDMAP VALUES(59,'deleteCollabsWithInvalidEmail',NULL,'504b03041400080808002493445800000000000000000000000007000000636f6e74656e740dccbb0d80300c05c055222fc002491a44c104d4069ec092f3516210e393fe743e71752f5a97920319e7ab90b31b09816a939e287a2b550e77205b631da83d18069f053aa130cc4595f7be89dd6b7e59e55c128bd214fd34fef803504b07083292f7c95b00000065000000504b01021400140008080800249344583292f7c95b00000065000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000900000000000',FALSE,'2024-02-04 18:25:08.279000','2024-02-04 18:25:08.279000',34,34) -INSERT INTO MINDMAP VALUES(60,'Welcome foo first name','','504b03041400080808002493445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080024934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:09.231000','2024-02-04 18:25:09.231000',35,35) -INSERT INTO MINDMAP VALUES(61,'new title for map','updated map description','504b03041400080808002493445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080024934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',FALSE,'2024-02-04 18:25:09.584000','2024-02-04 18:25:09.895000',35,35) -INSERT INTO MINDMAP VALUES(62,'Welcome foo first name','','504b03041400080808002593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080025934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:10.527000','2024-02-04 18:25:10.527000',36,36) -INSERT INTO MINDMAP VALUES(63,'Welcome foo first name','','504b03041400080808002593445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080025934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:11.560000','2024-02-04 18:25:11.560000',37,37) -INSERT INTO MINDMAP VALUES(64,'Welcome foo first name','','504b03041400080808002693445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080026934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:12.829000','2024-02-04 18:25:12.829000',38,38) -INSERT INTO MINDMAP VALUES(65,'Welcome foo first name','','504b03041400080808002693445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080026934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:13.853000','2024-02-04 18:25:13.853000',39,39) -INSERT INTO MINDMAP VALUES(66,'Welcome foo first name','','504b03041400080808002793445800000000000000000000000007000000636f6e74656e74ad575d6fda4a107defaf98ba8fd7047f82b98454294975a35baa48a1ea4355456b7bc1ab182fda5dc2e5dfdfd9b5f9b42934741329c2deec9c9939e7ec703d237328c88c0eac8524536ac12b1592f1626029524cb975f30e705d2b3e670924b45082e4f84e2c70aba2ffa981f50f5f82e2f0a48850f0d102960e2cd782092fd4935ae57872bfff819ad5eff72d88a7439e7331b03e38047fa22a8409c3125e9803249b16cf19cde7567be7758962ce255306a2db75ed56e058c0454af144678d69ac374a78147c4e85625456b06ab802b30e7079a11353dfdac4ad562c36c023270c7b3bc01bc027a44868be0bbf3105af17daad9eb749c15da7709ba6f095ab3574df3d08674e2b70c3cdf5fb1fc3bbdbf1ed8f71c624e02f01c966f39c827e0defaf7efebcb96e9badfb58da06cc0980be873576dda85e648df00b2b5ea46eff771ac32312a882db3d5ee88634723c05160289952935ffbbdd5e2e975753cea739bd4af80c03aee69aa1a25ecff372701dcc21d8a4e0af53182d72c574a5c6f8110c5a59ebbb5ea6055e13f6c35881e33573d290a76aa67f589ec9c4c1a5cbd33e3786ebd74953655006090f82f4639ea77da648ce9273e338b6bbe5a6b79117b6a30ad2d90b3266332afb9d7e432267760a33f3b75c0bd611efd8644205da0f3c6564ae5394faefc0123451047952c2891a9b778c89a7b519d9ad4ea79eff67d4f60a1e50ef55ad03bf891a1b439890843e2f91e4278b527f7008aae546fba836cdbf4fcd16f8265931857fe92ae644a42540cf3b2ec89acf6d8c90a4a93be91ef5b90c8f7f7e59c73955cd961f44da497abbd230d83abf65163ad9ade78df82b854f542d292da0b2fdef4c6530ce28dc0ac197d2d89ff9af3710b2e587e87f51b453ee268aade5a7ef4054876e009aa2ee88b1962ad1e08fd213a175ed9696f9a1ad3d0a2a25dc178a0a0d431b35812716e71a9729d25193f30e5de3b70075d1673b0d8651021a2a91b7475491bff6a00d3396a7a760d5afe30b4b87d76e83cf8cb8a0f0f10a86e8912f803c9719172a5928bc5563a45ad9c8d0d91b4b4e6ad6f503bbd75016f432812d290ffd850a76244953124f268792ac3957e8db9db07e073d14af0c4782cf82d12235f7369e9b636682a82ab7dedbfbef791dbb6994b99fc5340556c0a79c4fd7a39873411ce4fdae8f6c69b6408acb0c567c2160c48a1470bcade29dc7eb73fcb71bd95db72eba7dfb1df185ac2afa26eb4d7b71e846bfb6de9989719aeb5ed7f6bc43d70d2e30dd3b8e85a65b919052bd1bcb535939515de8bc816b87dd5d3a9989e30fe2d63887a47825a5140445155497c885d0b1e4fb8237b671097441a64090d177f89d667dd13d56112f04eb7770caf3eb8cfe2669d94acef39854b3abd73daa97fd0f82e6444790199b831489c1fc50cd2229956afbc002bc99e8d80cf9181dbdc9dcdcebef99525fabd59309c94bce5fb751db37effe07504b0708d418d5de27040000c10e0000504b0102140014000808080027934458d418d5de27040000c10e0000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000005c0400000000',FALSE,'2024-02-04 18:25:15.336000','2024-02-04 18:25:15.336000',40,40) -INSERT INTO LABEL VALUES(0,'removeLabelFromMindmap',10,NULL,'red') -INSERT INTO LABEL VALUES(1,'Label 1 - ',30,NULL,'COLOR') -INSERT INTO LABEL VALUES(3,'Label 1 - ',40,NULL,'#000000') -INSERT INTO LABEL VALUES(4,'Label 2 - ',40,NULL,'#000000') -INSERT INTO R_LABEL_MINDMAP VALUES(50,1) -INSERT INTO MINDMAP_HISTORY VALUES(0,'504b03041400080808001193445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080011934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',9,'2024-02-04 18:24:34.773000',8) -INSERT INTO MINDMAP_HISTORY VALUES(1,'504b03041400080808001493445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080014934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',17,'2024-02-04 18:24:40.457000',13) -INSERT INTO MINDMAP_HISTORY VALUES(2,'504b03041400080808001993445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a2c43c858adc1c85927ca078718942516a596a5189427246625e7a6ab142716a51596672aaba9d8d3ec80000504b070851cb12a34300000046000000504b010214001400080808001993445851cb12a34300000046000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000780000000000',35,'2024-02-04 18:24:51.508000',23) -INSERT INTO MINDMAP_HISTORY VALUES(3,'504b03041400080808001993445800000000000000000000000007000000636f6e74656e7415cc410e80200c04c0afec8da31f40fe025243134b0d6e94e7abc99c275a3e53ec5e0594c935b0e9854fee9876e051369857dd75cb54efa0a30886dc322835a4b8fcc50b504b0708647aca3f4400000048000000504b0102140014000808080019934458647aca3f4400000048000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000790000000000',35,'2024-02-04 18:24:51.820000',23) -INSERT INTO MINDMAP_HISTORY VALUES(4,'504b03041400080808001993445800000000000000000000000007000000636f6e74656e74b3c94d2cb0b3c9cb4f49552849ad28b1552fc9c82c5600a2c43c858adc1c85927ca078718942516a596a5189427246625e7a6ab142716a51596672aaba9d8d3ec80000504b070851cb12a34300000046000000504b010214001400080808001993445851cb12a34300000046000000070000000000000000000000000000000000636f6e74656e74504b0506000000000100010035000000780000000000',35,'2024-02-04 18:24:53.099000',23) -INSERT INTO MINDMAP_HISTORY VALUES(5,'504b03041400080808001b93445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b010214001400080808001b934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',39,'2024-02-04 18:24:55.607000',25) -INSERT INTO MINDMAP_HISTORY VALUES(6,'504b03041400080808002493445800000000000000000000000007000000636f6e74656e74b3c94d2cb02bc9c82c5600a2bcfc1285b2c49ccc141b7d903000504b0708ac5f2c5f1a0000001c000000504b0102140014000808080024934458ac5f2c5f1a0000001c000000070000000000000000000000000000000000636f6e74656e74504b05060000000001000100350000004f0000000000',61,'2024-02-04 18:25:09.896000',35) -INSERT INTO COLLABORATION_PROPERTIES VALUES(0,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(1,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(2,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(3,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(4,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(5,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(8,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(9,FALSE,'{zoom:x}') -INSERT INTO COLLABORATION_PROPERTIES VALUES(10,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(11,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(12,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(13,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(14,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(15,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(16,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(17,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(18,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(19,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(20,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(21,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(22,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(23,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(24,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(25,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(26,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(28,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(32,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(34,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(35,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(36,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(37,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(38,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(39,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(40,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(41,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(42,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(43,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(44,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(45,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(47,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(48,TRUE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(49,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(50,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(51,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(52,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(53,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(55,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(56,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(57,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(58,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(59,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(60,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(61,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(62,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(63,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(64,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(65,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(66,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(67,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(68,FALSE,'{zoom:x}') -INSERT INTO COLLABORATION_PROPERTIES VALUES(69,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(70,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(71,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(72,FALSE,NULL) -INSERT INTO COLLABORATION_PROPERTIES VALUES(73,FALSE,NULL) -INSERT INTO COLLABORATION VALUES(0,3,0,0,0) -INSERT INTO COLLABORATION VALUES(1,3,1,1,0) -INSERT INTO COLLABORATION VALUES(2,4,2,2,0) -INSERT INTO COLLABORATION VALUES(3,5,3,3,0) -INSERT INTO COLLABORATION VALUES(4,6,4,4,0) -INSERT INTO COLLABORATION VALUES(5,6,5,5,0) -INSERT INTO COLLABORATION VALUES(8,8,8,8,0) -INSERT INTO COLLABORATION VALUES(9,8,9,9,0) -INSERT INTO COLLABORATION VALUES(10,9,10,10,0) -INSERT INTO COLLABORATION VALUES(11,9,11,11,0) -INSERT INTO COLLABORATION VALUES(12,10,12,12,0) -INSERT INTO COLLABORATION VALUES(13,10,13,13,0) -INSERT INTO COLLABORATION VALUES(14,11,14,14,0) -INSERT INTO COLLABORATION VALUES(15,11,15,15,0) -INSERT INTO COLLABORATION VALUES(16,12,16,15,1) -INSERT INTO COLLABORATION VALUES(17,13,17,16,0) -INSERT INTO COLLABORATION VALUES(18,13,18,17,0) -INSERT INTO COLLABORATION VALUES(19,14,19,18,0) -INSERT INTO COLLABORATION VALUES(20,14,20,19,0) -INSERT INTO COLLABORATION VALUES(21,15,21,20,0) -INSERT INTO COLLABORATION VALUES(22,15,22,21,0) -INSERT INTO COLLABORATION VALUES(23,16,23,22,0) -INSERT INTO COLLABORATION VALUES(24,16,24,21,1) -INSERT INTO COLLABORATION VALUES(25,17,25,23,0) -INSERT INTO COLLABORATION VALUES(26,17,26,24,0) -INSERT INTO COLLABORATION VALUES(28,18,28,24,1) -INSERT INTO COLLABORATION VALUES(32,20,32,28,0) -INSERT INTO COLLABORATION VALUES(34,21,34,30,0) -INSERT INTO COLLABORATION VALUES(35,21,35,31,0) -INSERT INTO COLLABORATION VALUES(36,22,36,32,0) -INSERT INTO COLLABORATION VALUES(37,22,37,33,0) -INSERT INTO COLLABORATION VALUES(38,23,38,34,0) -INSERT INTO COLLABORATION VALUES(39,23,39,35,0) -INSERT INTO COLLABORATION VALUES(40,24,40,36,0) -INSERT INTO COLLABORATION VALUES(41,24,41,37,0) -INSERT INTO COLLABORATION VALUES(42,25,42,38,0) -INSERT INTO COLLABORATION VALUES(43,25,43,39,0) -INSERT INTO COLLABORATION VALUES(44,26,44,40,0) -INSERT INTO COLLABORATION VALUES(45,26,45,41,0) -INSERT INTO COLLABORATION VALUES(47,27,47,42,0) -INSERT INTO COLLABORATION VALUES(48,27,48,43,0) -INSERT INTO COLLABORATION VALUES(49,28,49,44,0) -INSERT INTO COLLABORATION VALUES(50,28,50,45,0) -INSERT INTO COLLABORATION VALUES(51,28,51,46,0) -INSERT INTO COLLABORATION VALUES(52,29,52,47,0) -INSERT INTO COLLABORATION VALUES(53,29,53,48,0) -INSERT INTO COLLABORATION VALUES(55,12,55,48,2) -INSERT INTO COLLABORATION VALUES(56,30,56,49,0) -INSERT INTO COLLABORATION VALUES(57,30,57,50,0) -INSERT INTO COLLABORATION VALUES(58,31,58,51,0) -INSERT INTO COLLABORATION VALUES(59,31,59,52,0) -INSERT INTO COLLABORATION VALUES(60,31,60,53,0) -INSERT INTO COLLABORATION VALUES(61,32,61,54,0) -INSERT INTO COLLABORATION VALUES(62,32,62,55,0) -INSERT INTO COLLABORATION VALUES(63,33,63,56,0) -INSERT INTO COLLABORATION VALUES(64,33,64,57,0) -INSERT INTO COLLABORATION VALUES(65,34,65,58,0) -INSERT INTO COLLABORATION VALUES(66,34,66,59,0) -INSERT INTO COLLABORATION VALUES(67,35,67,60,0) -INSERT INTO COLLABORATION VALUES(68,35,68,61,0) -INSERT INTO COLLABORATION VALUES(69,36,69,62,0) -INSERT INTO COLLABORATION VALUES(70,37,70,63,0) -INSERT INTO COLLABORATION VALUES(71,38,71,64,0) -INSERT INTO COLLABORATION VALUES(72,39,72,65,0) -INSERT INTO COLLABORATION VALUES(73,40,73,66,0) diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index 4b457e4e..ef9e7666 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -1,8 +1,10 @@ package com.wisemapping.config.rest; +import com.wisemapping.filter.JwtAuthenticationFilter; import com.wisemapping.rest.MindmapController; import jakarta.servlet.http.HttpServletResponse; import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -11,6 +13,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; import org.springframework.web.servlet.handler.HandlerMappingIntrospector; @@ -21,6 +24,10 @@ import static org.springframework.security.config.Customizer.withDefaults; @Import({InterceptorsConfig.class}) @EnableWebSecurity public class RestAppConfig { + + @Autowired + private JwtAuthenticationFilter jwtAuthenticationFilter; + @Bean MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) { return new MvcRequestMatcher.Builder(introspector); @@ -30,6 +37,7 @@ public class RestAppConfig { SecurityFilterChain apiSecurityFilterChain(@NotNull final HttpSecurity http, @NotNull final MvcRequestMatcher.Builder mvc) throws Exception { return http .securityMatcher("/**") + .addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests(auth -> auth .requestMatchers(mvc.pattern("/api/restfull/users/")).permitAll() .requestMatchers(mvc.pattern("/api/restfull/authenticate")).permitAll() diff --git a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java new file mode 100644 index 00000000..ca177411 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java @@ -0,0 +1,64 @@ +package com.wisemapping.filter; + +import com.wisemapping.security.JwtTokenUtil; +import com.wisemapping.security.UserDetails; +import com.wisemapping.security.UserDetailsService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Component +public class JwtAuthenticationFilter extends OncePerRequestFilter { + @Autowired + private UserDetailsService userDetailsService; + + @Autowired + private JwtTokenUtil jwtTokenUtil; + + final private static Logger logger = LogManager.getLogger(); + + @Override + protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) + throws ServletException, IOException { + final String authorizationHeader = request.getHeader("Authorization"); + + String username = null; + String jwtToken = null; + + // Extract username from token ... + if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { + jwtToken = authorizationHeader.substring(7); + try { + username = jwtTokenUtil.extractFromJwtToken(jwtToken); + } catch (Exception e) { + // Handle token extraction/validation errors + logger.debug("Error extracting username from token: " + e.getMessage()); + } + } + + if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + final UserDetails userDetails = userDetailsService.loadUserByUsername(username); + + if (jwtTokenUtil.validateJwtToken(jwtToken)) { + final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( + userDetails, null, userDetails.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + } + + filterChain.doFilter(request, response); + } +} diff --git a/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java index 363b3b9a..402eec38 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java @@ -21,8 +21,10 @@ package com.wisemapping.rest; import com.wisemapping.rest.model.RestJwtUser; import com.wisemapping.security.JwtTokenUtil; import com.wisemapping.security.UserDetailsService; +import jakarta.servlet.http.HttpServletResponse; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; @@ -50,7 +52,7 @@ public class JwtAuthController { private JwtTokenUtil jwtTokenUtil; @RequestMapping(value = "/authenticate", method = RequestMethod.POST) - public ResponseEntity createAuthenticationToken(@RequestBody RestJwtUser user) throws Exception { + public ResponseEntity createAuthenticationToken(@RequestBody RestJwtUser user, @NotNull HttpServletResponse response) throws Exception { // Is a valid user ? authenticate(user.getUsername(), user.getPassword()); @@ -60,6 +62,10 @@ public class JwtAuthController { .loadUserByUsername(user.getUsername()); final String token = jwtTokenUtil.generateJwtToken(userDetails); + + // Add token in the header ... + response.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token); + return ResponseEntity.ok(token); } diff --git a/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java index 6f752bed..da80fc82 100644 --- a/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java +++ b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java @@ -37,12 +37,12 @@ public class JwtTokenUtil implements Serializable { return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret)); } - public String getUserNameFromJwtToken(String token) { + public String extractFromJwtToken(String token) { return Jwts.parserBuilder().setSigningKey(key()).build() .parseClaimsJws(token).getBody().getSubject(); } - public boolean validateJwtToken(String authToken) { + public boolean validateJwtToken(@NotNull String authToken) { try { Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken); return true; diff --git a/wise-api/src/main/resources/application.yml b/wise-api/src/main/resources/application.yml index be59037e..b911ec91 100755 --- a/wise-api/src/main/resources/application.yml +++ b/wise-api/src/main/resources/application.yml @@ -8,9 +8,9 @@ spring: name: wisemapping-api title: wisemapping-api datasource: + url: jdbc:hsqldb:mem:wisemapping driver-class-name: org.hsqldb.jdbc.JDBCDriver password: '' - url: jdbc:hsqldb:file:${database.base.url}/db/wisemapping username: sa jpa: hibernate: diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java index 3f4b45c2..cbda0815 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java @@ -27,6 +27,7 @@ import com.wisemapping.rest.JwtAuthController; import com.wisemapping.rest.model.RestJwtUser; import com.wisemapping.rest.model.RestUser; import com.wisemapping.rest.model.RestUserRegistration; +import com.wisemapping.security.JwtTokenUtil; import com.wisemapping.service.UserService; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -35,10 +36,12 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; import static com.wisemapping.test.rest.RestHelper.createDummyUser; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; @@ -53,6 +56,9 @@ public class RestJwtAuthControllerTest { @Autowired private ObjectMapper objectMapper; + @Autowired + JwtTokenUtil jwtTokenUtil; + @Autowired private MockMvc mockMvc; @@ -60,15 +66,18 @@ public class RestJwtAuthControllerTest { private UserService userService; @Test - void generateTockenValidUser() throws Exception { + void generateTokenValidUser() throws Exception { final RestJwtUser user = new RestJwtUser("test@wisemapping.org", "test"); final String userJson = objectMapper.writeValueAsString(user); - mockMvc.perform( + final MvcResult result = mockMvc.perform( post("/api/restfull/authenticate"). contentType(MediaType.APPLICATION_JSON) .content(userJson)) - .andExpect(status().isOk()); + .andExpect(status().isOk()).andReturn(); + + + assertTrue(jwtTokenUtil.validateJwtToken(result.getResponse().getContentAsString())); } @Test @@ -81,6 +90,7 @@ public class RestJwtAuthControllerTest { contentType(MediaType.APPLICATION_JSON) .content(userJson)) .andExpect(status().is4xxClientError()); + } @Test @@ -93,6 +103,7 @@ public class RestJwtAuthControllerTest { contentType(MediaType.APPLICATION_JSON) .content(userJson)) .andExpect(status().is4xxClientError()); - } + + } } From 34a5328a2c003458d9aaa8d38b6b15991f517c5a Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 20:53:24 -0800 Subject: [PATCH 058/110] Complete JWT token support. --- .../filter/JwtAuthenticationFilter.java | 66 ++++++++++++------- .../wisemapping/rest/JwtAuthController.java | 4 +- .../wisemapping/rest/model/RestJwtUser.java | 15 ++--- .../wisemapping/security/JwtTokenUtil.java | 6 +- wise-api/src/main/resources/application.yml | 16 +++-- 5 files changed, 64 insertions(+), 43 deletions(-) diff --git a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java index ca177411..29b41939 100644 --- a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java +++ b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java @@ -18,9 +18,11 @@ import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; +import java.util.Optional; @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { + private static final String BEARER_TOKEN_PREFIX = "Bearer "; @Autowired private UserDetailsService userDetailsService; @@ -32,33 +34,51 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException { - final String authorizationHeader = request.getHeader("Authorization"); - String username = null; - String jwtToken = null; - // Extract username from token ... - if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { - jwtToken = authorizationHeader.substring(7); - try { - username = jwtTokenUtil.extractFromJwtToken(jwtToken); - } catch (Exception e) { - // Handle token extraction/validation errors - logger.debug("Error extracting username from token: " + e.getMessage()); + final Optional token = getJwtTokenFromRequest(request); + if (token.isPresent() && SecurityContextHolder.getContext().getAuthentication() == null) { + // Extract email from token ... + final Optional email = extractEmailFromToken(token.get()); + + if (email.isPresent() && jwtTokenUtil.validateJwtToken(token.get())) { + // Is it an existing user ? + final UserDetails userDetails = userDetailsService.loadUserByUsername(email.get()); + if (userDetails != null) { + final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( + userDetails, null, userDetails.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } else { + logger.trace("User " + email.get() + " could not be found"); + } } } - - if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { - final UserDetails userDetails = userDetailsService.loadUserByUsername(username); - - if (jwtTokenUtil.validateJwtToken(jwtToken)) { - final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( - userDetails, null, userDetails.getAuthorities()); - authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - SecurityContextHolder.getContext().setAuthentication(authenticationToken); - } - } - filterChain.doFilter(request, response); } + + private Optional extractEmailFromToken(final @NotNull String token) { + Optional result = Optional.empty(); + try { + result = Optional.of(jwtTokenUtil.extractFromJwtToken(token)); + } catch (Exception e) { + // Handle token extraction/validation errors + logger.debug("Error extracting email from token: " + e.getMessage()); + } + return result; + } + + private static Optional getJwtTokenFromRequest(@NotNull HttpServletRequest request) { + Optional result = Optional.empty(); + + final String authorizationHeader = request.getHeader("Authorization"); + if (authorizationHeader != null) { + if (authorizationHeader.startsWith(BEARER_TOKEN_PREFIX)) { + logger.trace("JWT Bearer token found"); + final String token = authorizationHeader.substring(BEARER_TOKEN_PREFIX.length()); + result = Optional.of(token); + } + } + return result; + } } diff --git a/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java index 402eec38..95e5b969 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java @@ -55,11 +55,11 @@ public class JwtAuthController { public ResponseEntity createAuthenticationToken(@RequestBody RestJwtUser user, @NotNull HttpServletResponse response) throws Exception { // Is a valid user ? - authenticate(user.getUsername(), user.getPassword()); + authenticate(user.getEmail(), user.getPassword()); // Create token ... final UserDetails userDetails = userDetailsService - .loadUserByUsername(user.getUsername()); + .loadUserByUsername(user.getEmail()); final String token = jwtTokenUtil.generateJwtToken(userDetails); diff --git a/wise-api/src/main/java/com/wisemapping/rest/model/RestJwtUser.java b/wise-api/src/main/java/com/wisemapping/rest/model/RestJwtUser.java index 0eb10aa1..a4f519ba 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/model/RestJwtUser.java +++ b/wise-api/src/main/java/com/wisemapping/rest/model/RestJwtUser.java @@ -33,21 +33,20 @@ import org.jetbrains.annotations.NotNull; @JsonInclude(JsonInclude.Include.NON_NULL) public class RestJwtUser { - private String username; + private String email; private String password; - - public RestJwtUser(@NotNull String username, @NotNull String password) { - this.setUsername(username); + public RestJwtUser(@NotNull String email, @NotNull String password) { + this.setEmail(email); this.setPassword(password); } - public String getUsername() { - return this.username; + public String getEmail() { + return this.email; } - public void setUsername(String username) { - this.username = username; + public void setEmail(String email) { + this.email = email; } public String getPassword() { diff --git a/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java index da80fc82..3d751907 100644 --- a/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java +++ b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java @@ -21,14 +21,14 @@ public class JwtTokenUtil implements Serializable { @Value("${app.jwt.secret}") private String jwtSecret; - @Value("${app.jwt.expirationMs}") - private int jwtExpirationMs; + @Value("${app.jwt.expirationMin}") + private int jwtExpirationMin; public String generateJwtToken(@NotNull final UserDetails user) { return Jwts.builder() .setSubject((user.getUsername())) .setIssuedAt(new Date()) - .setExpiration(new Date((new Date()).getTime() + jwtExpirationMs)) + .setExpiration(new Date((new Date()).getTime() + jwtExpirationMin * 1000L * 60)) .signWith(key(), SignatureAlgorithm.HS256) .compact(); } diff --git a/wise-api/src/main/resources/application.yml b/wise-api/src/main/resources/application.yml index b911ec91..b02c1c65 100755 --- a/wise-api/src/main/resources/application.yml +++ b/wise-api/src/main/resources/application.yml @@ -29,12 +29,20 @@ spring: mode: always platform: hsqldb +# Login ... +logging: + level: + org: + apache: + tomcat: INFO + root: TRACE + # Application Configuration. app: jwt: secret: dlqxKAg685SaKhsQXIMeM=JWCw3bkl3Ei3Tb7LMlnd19oMd66burPNlJ0Po1qguyjgpakQTk2CN3 - expirationMs: 10000 + expirationMin: 10080 # One week admin: user: admin@wisemapping.org @@ -48,12 +56,6 @@ google: enabled: true secretKey: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe siteKey: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI -logging: - level: - org: - apache: - tomcat: INFO - root: INFO mail: password: '' serverSendEmail: root@localhost From 96b6ff3841d7f6ab68c0798048859c55ae4034fc Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 4 Feb 2024 21:10:48 -0800 Subject: [PATCH 059/110] Fix typo on path. --- .../config/rest/RestAppConfig.java | 12 +++++----- .../wisemapping/rest/AccountController.java | 2 +- .../com/wisemapping/rest/AdminController.java | 4 ++-- .../wisemapping/rest/JwtAuthController.java | 2 +- .../com/wisemapping/rest/LabelController.java | 4 ++-- .../wisemapping/rest/MindmapController.java | 6 ++--- .../com/wisemapping/rest/UserController.java | 4 ++-- .../com/wisemapping/test/rest/RestHelper.java | 2 +- .../test/rest/RestJwtAuthControllerTest.java | 6 ++--- .../test/rest/RestLabelControllerTest.java | 2 +- .../test/rest/RestMindmapControllerTest.java | 24 +++++++++---------- .../test/rest/RestUserControllerTest.java | 8 +++---- 12 files changed, 38 insertions(+), 38 deletions(-) diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index ef9e7666..65546bd1 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -39,12 +39,12 @@ public class RestAppConfig { .securityMatcher("/**") .addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests(auth -> auth - .requestMatchers(mvc.pattern("/api/restfull/users/")).permitAll() - .requestMatchers(mvc.pattern("/api/restfull/authenticate")).permitAll() - .requestMatchers(mvc.pattern("/api/restfull/users/resetPassword")).permitAll() - .requestMatchers(mvc.pattern("/api/restfull/oauth2/googlecallback")).permitAll() - .requestMatchers(mvc.pattern("/api/restfull/oauth2/confirmaccountsync")).permitAll() - .requestMatchers(mvc.pattern("/api/restfull/admin/**")).hasAnyRole("ADMIN") + .requestMatchers(mvc.pattern("/api/restful/users/")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/authenticate")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/users/resetPassword")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/oauth2/googlecallback")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/oauth2/confirmaccountsync")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/admin/**")).hasAnyRole("ADMIN") .requestMatchers(mvc.pattern("/**")).hasAnyRole("USER", "ADMIN") .anyRequest().authenticated() ) diff --git a/wise-api/src/main/java/com/wisemapping/rest/AccountController.java b/wise-api/src/main/java/com/wisemapping/rest/AccountController.java index 52a870dc..5435c9c3 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/AccountController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/AccountController.java @@ -39,7 +39,7 @@ import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping("/api/restfull/account/") +@RequestMapping("/api/restful/account/") @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") public class AccountController extends BaseController { @Qualifier("userService") diff --git a/wise-api/src/main/java/com/wisemapping/rest/AdminController.java b/wise-api/src/main/java/com/wisemapping/rest/AdminController.java index 3c4d1ac3..a82e6695 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/AdminController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/AdminController.java @@ -36,7 +36,7 @@ import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping("/api/restfull/admin") +@RequestMapping("/api/restful/admin") @PreAuthorize("isAuthenticated() and hasRole('ROLE_ADMIN')") public class AdminController extends BaseController { @Qualifier("userService") @@ -101,7 +101,7 @@ public class AdminController extends BaseController { // Finally create the user ... delegated.setAuthenticationType(AuthenticationType.DATABASE); userService.createUser(delegated, false, true); - response.setHeader("Location", "/api/restfull/admin/users/" + user.getId()); + response.setHeader("Location", "/api/restful/admin/users/" + user.getId()); } @RequestMapping(method = RequestMethod.PUT, value = "/users/{id}/password", consumes = {"text/plain"}) diff --git a/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java index 95e5b969..879ec8a1 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java @@ -39,7 +39,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController @CrossOrigin -@RequestMapping("/api/restfull") +@RequestMapping("/api/restful") public class JwtAuthController { @Autowired diff --git a/wise-api/src/main/java/com/wisemapping/rest/LabelController.java b/wise-api/src/main/java/com/wisemapping/rest/LabelController.java index 694524f4..8136559d 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/LabelController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/LabelController.java @@ -40,7 +40,7 @@ import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping("/api/restfull/labels") +@RequestMapping("/api/restful/labels") @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") public class LabelController extends BaseController { @@ -63,7 +63,7 @@ public class LabelController extends BaseController { final Label label = createLabel(restLabel); // Return the new created label ... - response.setHeader("Location", "/api/restfull/labels/" + label.getId()); + response.setHeader("Location", "/api/restful/labels/" + label.getId()); response.setHeader("ResourceId", Long.toString(label.getId())); } diff --git a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java index 13850c9c..f4784bc3 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java @@ -46,7 +46,7 @@ import java.util.stream.Collectors; @RestController -@RequestMapping("/api/restfull/maps") +@RequestMapping("/api/restful/maps") public class MindmapController extends BaseController { private final Logger logger = LogManager.getLogger(); @@ -548,7 +548,7 @@ public class MindmapController extends BaseController { mindmapService.addMindmap(mindmap, user); // Return the new created map ... - response.setHeader("Location", "/api/restfull/maps/" + mindmap.getId()); + response.setHeader("Location", "/api/restful/maps/" + mindmap.getId()); response.setHeader("ResourceId", Integer.toString(mindmap.getId())); } @@ -576,7 +576,7 @@ public class MindmapController extends BaseController { mindmapService.addMindmap(clonedMap, user); // Return the new created map ... - response.setHeader("Location", "/api/restfull/maps/" + clonedMap.getId()); + response.setHeader("Location", "/api/restful/maps/" + clonedMap.getId()); response.setHeader("ResourceId", Integer.toString(clonedMap.getId())); } diff --git a/wise-api/src/main/java/com/wisemapping/rest/UserController.java b/wise-api/src/main/java/com/wisemapping/rest/UserController.java index b10b8ed0..a8ca2c2b 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/UserController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/UserController.java @@ -48,7 +48,7 @@ import java.util.Arrays; import java.util.List; @RestController -@RequestMapping("/api/restfull/users") +@RequestMapping("/api/restful/users") @CrossOrigin public class UserController extends BaseController { @@ -99,7 +99,7 @@ public class UserController extends BaseController { user.setAuthenticationType(AuthenticationType.DATABASE); userService.createUser(user, false, true); - response.setHeader("Location", "/api/restfull/users/" + user.getId()); + response.setHeader("Location", "/api/restful/users/" + user.getId()); } @RequestMapping(method = RequestMethod.PUT, value = "/resetPassword", produces = { "application/json" }) diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestHelper.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestHelper.java index d2538f74..9a4e84e3 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestHelper.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestHelper.java @@ -12,7 +12,7 @@ import java.util.ArrayList; import java.util.List; public class RestHelper { - public static final String BASE_REST_URL = "/api/restfull"; + public static final String BASE_REST_URL = "/api/restful"; static HttpHeaders createHeaders(@NotNull MediaType mediaType) { List acceptableMediaTypes = new ArrayList<>(); diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java index cbda0815..f00f44ff 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java @@ -71,7 +71,7 @@ public class RestJwtAuthControllerTest { final String userJson = objectMapper.writeValueAsString(user); final MvcResult result = mockMvc.perform( - post("/api/restfull/authenticate"). + post("/api/restful/authenticate"). contentType(MediaType.APPLICATION_JSON) .content(userJson)) .andExpect(status().isOk()).andReturn(); @@ -86,7 +86,7 @@ public class RestJwtAuthControllerTest { final String userJson = objectMapper.writeValueAsString(user); mockMvc.perform( - post("/api/restfull/authenticate"). + post("/api/restful/authenticate"). contentType(MediaType.APPLICATION_JSON) .content(userJson)) .andExpect(status().is4xxClientError()); @@ -99,7 +99,7 @@ public class RestJwtAuthControllerTest { final String userJson = objectMapper.writeValueAsString(user); mockMvc.perform( - post("/api/restfull/authenticate"). + post("/api/restful/authenticate"). contentType(MediaType.APPLICATION_JSON) .content(userJson)) .andExpect(status().is4xxClientError()); diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestLabelControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestLabelControllerTest.java index 6740e10b..bd3ed821 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestLabelControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestLabelControllerTest.java @@ -134,7 +134,7 @@ public class RestLabelControllerTest { // Create a new label ... final HttpEntity createUserEntity = new HttpEntity<>(restLabel, requestHeaders); - final ResponseEntity result = template.exchange("/api/restfull/labels", HttpMethod.POST, createUserEntity, String.class); + final ResponseEntity result = template.exchange("/api/restful/labels", HttpMethod.POST, createUserEntity, String.class); if (!result.getStatusCode().is2xxSuccessful()) { throw new IllegalStateException(result.toString()); } diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java index d26b3ebe..078e2928 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java @@ -128,7 +128,7 @@ public class RestMindmapControllerTest { // Add map with same name ... HttpEntity createUserEntity = new HttpEntity<>(requestHeaders); - final ResponseEntity response = restTemplate.exchange("/api/restfull/maps?title=" + title, HttpMethod.POST, createUserEntity, String.class); + final ResponseEntity response = restTemplate.exchange("/api/restful/maps?title=" + title, HttpMethod.POST, createUserEntity, String.class); assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); assertTrue(Objects.requireNonNull(response.getBody()).contains("You have already a map with the same name")); } @@ -254,7 +254,7 @@ public class RestMindmapControllerTest { addNewMap(secondTemplate, title2); final TestRestTemplate superadminTemplate = this.restTemplate.withBasicAuth("admin@wisemapping.org", "test"); - final ResponseEntity exchange = superadminTemplate.exchange("/api/restfull/admin/users/" + secondUser.getId(), HttpMethod.DELETE, null, String.class); + final ResponseEntity exchange = superadminTemplate.exchange("/api/restful/admin/users/" + secondUser.getId(), HttpMethod.DELETE, null, String.class); assertTrue(exchange.getStatusCode().is2xxSuccessful(), "Status Code:" + exchange.getStatusCode() + "- " + exchange.getBody()); // Validate that the two maps are there ... @@ -490,15 +490,15 @@ public class RestMindmapControllerTest { // Create a sample map ... final String mapTitle = "removeLabelFromMindmap"; final URI mindmapUri = addNewMap(restTemplate, mapTitle); - final String mapId = mindmapUri.getPath().replace("/api/restfull/maps/", ""); + final String mapId = mindmapUri.getPath().replace("/api/restful/maps/", ""); // Assign label to map ... - String labelId = labelUri.getPath().replace("/api/restfull/labels/", ""); + String labelId = labelUri.getPath().replace("/api/restful/labels/", ""); HttpEntity labelEntity = new HttpEntity<>(labelId, requestHeaders); - restTemplate.postForLocation("/api/restfull/maps/" + mapId + "/labels", labelEntity); + restTemplate.postForLocation("/api/restful/maps/" + mapId + "/labels", labelEntity); // Remove label from map - final ResponseEntity exchange = restTemplate.exchange("/api/restfull//maps/" + mapId + "/labels/" + labelId, HttpMethod.DELETE, null, String.class); + final ResponseEntity exchange = restTemplate.exchange("/api/restful//maps/" + mapId + "/labels/" + labelId, HttpMethod.DELETE, null, String.class); assertTrue(exchange.getStatusCode().is2xxSuccessful()); @@ -535,12 +535,12 @@ public class RestMindmapControllerTest { // Create a sample map ... final String mapTitle = "Maps 1 - "; final URI mindmapUri = addNewMap(restTemplate, mapTitle); - final String mapId = mindmapUri.getPath().replace("/api/restfull/maps/", ""); + final String mapId = mindmapUri.getPath().replace("/api/restful/maps/", ""); // Assign label to map ... - String labelId = labelUri.getPath().replace("/api/restfull/labels/", ""); + String labelId = labelUri.getPath().replace("/api/restful/labels/", ""); HttpEntity labelEntity = new HttpEntity<>(labelId, requestHeaders); - restTemplate.postForLocation("/api/restfull/maps/" + mapId + "/labels", labelEntity); + restTemplate.postForLocation("/api/restful/maps/" + mapId + "/labels", labelEntity); // Check that the label has been assigned ... Optional mindmapInfo = fetchMap(requestHeaders, restTemplate, mapId); @@ -636,7 +636,7 @@ public class RestMindmapControllerTest { final String maps = fetchMaps(requestHeaders, restTemplate).getMindmapsInfo().stream().map(map -> String.valueOf(map.getId())).collect(Collectors.joining(",")); - final ResponseEntity exchange = restTemplate.exchange("/api/restfull/maps/batch?ids=" + maps, HttpMethod.DELETE, null, String.class); + final ResponseEntity exchange = restTemplate.exchange("/api/restful/maps/batch?ids=" + maps, HttpMethod.DELETE, null, String.class); assertTrue(exchange.getStatusCode().is2xxSuccessful(), "Status code:" + exchange.getStatusCode() + " - " + exchange.getBody()); // Validate that the two maps are there ... @@ -769,7 +769,7 @@ public class RestMindmapControllerTest { @NotNull private RestMindmapList fetchMaps(final HttpHeaders requestHeaders, final TestRestTemplate template) throws RestClientException { final HttpEntity findMapEntity = new HttpEntity<>(requestHeaders); - final ResponseEntity response = template.exchange("/api/restfull/maps/", HttpMethod.GET, findMapEntity, RestMindmapList.class); + final ResponseEntity response = template.exchange("/api/restful/maps/", HttpMethod.GET, findMapEntity, RestMindmapList.class); assertTrue(response.getStatusCode().is2xxSuccessful(), response.toString()); return Objects.requireNonNull(response.getBody()); @@ -804,7 +804,7 @@ public class RestMindmapControllerTest { // Create a new map ... final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_XML); HttpEntity createUserEntity = new HttpEntity<>(xml, requestHeaders); - return template.postForLocation("/api/restfull/maps?title=" + title, createUserEntity); + return template.postForLocation("/api/restful/maps?title=" + title, createUserEntity); } private URI addNewMap(@NotNull TestRestTemplate template, @NotNull String title) { diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java index f487c19e..661fd86a 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java @@ -66,7 +66,7 @@ public class RestUserControllerTest { final String userJson = objectMapper.writeValueAsString(result); mockMvc.perform( - post("/api/restfull/admin/users"). + post("/api/restful/admin/users"). contentType(MediaType.APPLICATION_JSON) .content(userJson) .with(user("test@wisemapping.org").roles("ADMIN"))) @@ -81,7 +81,7 @@ public class RestUserControllerTest { @Test void resetPasswordInvalidUser() throws Exception { this.mockMvc.perform - (put("/api/restfull/users/resetPassword?email=doesnotexist@example.com")) + (put("/api/restful/users/resetPassword?email=doesnotexist@example.com")) .andDo(print()) .andExpect(status().is4xxClientError()) .andExpect(content().string(containsString("The email provided is not a valid user account."))); @@ -91,7 +91,7 @@ public class RestUserControllerTest { void resetPasswordValidUser() throws Exception { final RestUser user = createUser(); this.mockMvc.perform - (put("/api/restfull/users/resetPassword?email=" + user.getEmail())) + (put("/api/restful/users/resetPassword?email=" + user.getEmail())) .andDo(print()) .andExpect(status().isOk()); } @@ -104,7 +104,7 @@ public class RestUserControllerTest { final String userJson = objectMapper.writeValueAsString(user); mockMvc.perform( - post("/api/restfull/users/"). + post("/api/restful/users/"). contentType(MediaType.APPLICATION_JSON) .content(userJson)) .andExpect(status().isCreated()); From d798358fec50ed6c1ad4b9cd4f0073b9a4bfe782 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Mon, 5 Feb 2024 21:21:34 -0800 Subject: [PATCH 060/110] Minor expoint fixes. --- .../wisemapping/filter/JwtAuthenticationFilter.java | 7 ++++--- .../java/com/wisemapping/rest/AccountController.java | 10 +++++----- .../main/java/com/wisemapping/rest/UserController.java | 1 - .../java/com/wisemapping/security/JwtTokenUtil.java | 9 +++++++-- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java index 29b41939..c0695515 100644 --- a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java +++ b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java @@ -34,9 +34,9 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException { - - final Optional token = getJwtTokenFromRequest(request); + + if (token.isPresent() && SecurityContextHolder.getContext().getAuthentication() == null) { // Extract email from token ... final Optional email = extractEmailFromToken(token.get()); @@ -65,6 +65,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { // Handle token extraction/validation errors logger.debug("Error extracting email from token: " + e.getMessage()); } + logger.trace("JWT token email:" + result); return result; } @@ -74,7 +75,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { final String authorizationHeader = request.getHeader("Authorization"); if (authorizationHeader != null) { if (authorizationHeader.startsWith(BEARER_TOKEN_PREFIX)) { - logger.trace("JWT Bearer token found"); + logger.trace("JWT Bearer token found."); final String token = authorizationHeader.substring(BEARER_TOKEN_PREFIX.length()); result = Optional.of(token); } diff --git a/wise-api/src/main/java/com/wisemapping/rest/AccountController.java b/wise-api/src/main/java/com/wisemapping/rest/AccountController.java index 5435c9c3..355c8c9a 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/AccountController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/AccountController.java @@ -39,7 +39,7 @@ import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping("/api/restful/account/") +@RequestMapping("/api/restful/account") @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") public class AccountController extends BaseController { @Qualifier("userService") @@ -54,7 +54,7 @@ public class AccountController extends BaseController { @Autowired private LabelService labelService; - @RequestMapping(method = RequestMethod.PUT, value = "password", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "/password", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changePassword(@RequestBody String password) throws PasswordTooLongException { if (password == null) { @@ -76,7 +76,7 @@ public class AccountController extends BaseController { return new RestUser(user); } - @RequestMapping(method = RequestMethod.PUT, value = "firstname", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "/firstname", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changeFirstname(@RequestBody String firstname) { if (firstname == null) { @@ -88,7 +88,7 @@ public class AccountController extends BaseController { userService.updateUser(user); } - @RequestMapping(method = RequestMethod.PUT, value = "lastname", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "/lastname", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changeLastName(@RequestBody String lastname) { if (lastname == null) { @@ -100,7 +100,7 @@ public class AccountController extends BaseController { userService.updateUser(user); } - @RequestMapping(method = RequestMethod.PUT, value = "locale", consumes = {"text/plain"}) + @RequestMapping(method = RequestMethod.PUT, value = "/locale", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changeLanguage(@RequestBody String language) { if (language == null) { diff --git a/wise-api/src/main/java/com/wisemapping/rest/UserController.java b/wise-api/src/main/java/com/wisemapping/rest/UserController.java index a8ca2c2b..8e04eb4c 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/UserController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/UserController.java @@ -49,7 +49,6 @@ import java.util.List; @RestController @RequestMapping("/api/restful/users") -@CrossOrigin public class UserController extends BaseController { @Qualifier("userService") diff --git a/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java index 3d751907..c33b7472 100644 --- a/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java +++ b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java @@ -6,6 +6,7 @@ import io.jsonwebtoken.security.Keys; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; @@ -37,15 +38,18 @@ public class JwtTokenUtil implements Serializable { return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret)); } + + @Nullable public String extractFromJwtToken(String token) { return Jwts.parserBuilder().setSigningKey(key()).build() .parseClaimsJws(token).getBody().getSubject(); } public boolean validateJwtToken(@NotNull String authToken) { + boolean result = false; try { Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken); - return true; + result = true; } catch (MalformedJwtException e) { logger.error("Invalid JWT token: {}", e.getMessage()); } catch (ExpiredJwtException e) { @@ -56,6 +60,7 @@ public class JwtTokenUtil implements Serializable { logger.error("JWT claims string is empty: {}", e.getMessage()); } - return false; + logger.trace("Is JWT token valid:" + result); + return result; } } \ No newline at end of file From 37d7a9bb6dc5abbeb27d9a46556b02bba416d931 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Tue, 6 Feb 2024 21:12:15 -0800 Subject: [PATCH 061/110] Add missing expoint test. --- .../test/rest/RestAccountControllerTest.java | 47 +++++++++++++------ .../test/rest/RestJwtAuthControllerTest.java | 11 ----- .../test/rest/RestUserControllerTest.java | 6 +-- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java index 2a64a3ee..9d94943f 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java @@ -18,27 +18,30 @@ package com.wisemapping.test.rest; - import com.wisemapping.config.common.CommonConfig; import com.wisemapping.config.rest.RestAppConfig; import com.wisemapping.rest.AdminController; import com.wisemapping.rest.MindmapController; import com.wisemapping.rest.UserController; import com.wisemapping.rest.model.RestUser; +import com.wisemapping.security.UserDetailsService; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.*; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import java.net.URI; import static com.wisemapping.test.rest.RestHelper.*; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; @SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, MindmapController.class, AdminController.class, UserController.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureMockMvc public class RestAccountControllerTest { private static final String ADMIN_USER = "admin@wisemapping.org"; private static final String ADMIN_PASSWORD = "test"; @@ -46,6 +49,9 @@ public class RestAccountControllerTest { @Autowired private TestRestTemplate restTemplate; + @Autowired + private UserDetailsService service; + static public RestAccountControllerTest create(@NotNull TestRestTemplate restTemplate) { final RestAccountControllerTest result = new RestAccountControllerTest(); result.restTemplate = restTemplate; @@ -53,27 +59,40 @@ public class RestAccountControllerTest { } @Test - public void deleteUser() { // Configure media types ... + public void deleteAccount() { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate adminRestTemplate = this.restTemplate.withBasicAuth(ADMIN_USER, ADMIN_PASSWORD); - final RestUser dummyUser = createDummyUser(); - createUser(requestHeaders, adminRestTemplate, dummyUser); + final RestUser newUser = createDummyUser(); + createUser(requestHeaders, adminRestTemplate, newUser); // Delete user ... - final TestRestTemplate dummyTemplate = this.restTemplate.withBasicAuth(dummyUser.getEmail(), "fooPassword"); - dummyTemplate.delete(BASE_REST_URL + "/account"); + final TestRestTemplate newUserTemplate = this.restTemplate.withBasicAuth(newUser.getEmail(), newUser.getPassword()); + final ResponseEntity exchange = newUserTemplate.exchange(BASE_REST_URL + "/account", HttpMethod.DELETE, null, String.class); + assertTrue(exchange.getStatusCode().is2xxSuccessful(), exchange.toString()); - // Is the user there ? - // Check that the user has been created ... -// try { -// findUser(requestHeaders, adminTemplate, location); -// fail("User could not be deleted !"); -// } catch (Exception e) { -// } + // Check that the account has been deleted ... + assertThrows(UsernameNotFoundException.class, () -> { + service.loadUserByUsername(newUser.getEmail()); + }); } + @Test + public void accessAccount() { + final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); + final TestRestTemplate adminRestTemplate = this.restTemplate.withBasicAuth(ADMIN_USER, ADMIN_PASSWORD); + + final RestUser newUser = createDummyUser(); + createUser(requestHeaders, adminRestTemplate, newUser); + + final TestRestTemplate newUserTemplate = this.restTemplate.withBasicAuth(newUser.getEmail(), newUser.getPassword()); + final ResponseEntity exchange = newUserTemplate.exchange(BASE_REST_URL + "/account", HttpMethod.GET, null, RestUser.class); + assertTrue(exchange.getStatusCode().is2xxSuccessful(), exchange.toString()); + assertEquals(exchange.getBody().getEmail(), newUser.getEmail()); + } + + @Test public RestUser createNewUser() { // Configure media types ... diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java index f00f44ff..1159e4d3 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java @@ -22,14 +22,10 @@ package com.wisemapping.test.rest; import com.fasterxml.jackson.databind.ObjectMapper; import com.wisemapping.config.common.CommonConfig; import com.wisemapping.config.rest.RestAppConfig; -import com.wisemapping.model.User; import com.wisemapping.rest.JwtAuthController; import com.wisemapping.rest.model.RestJwtUser; -import com.wisemapping.rest.model.RestUser; -import com.wisemapping.rest.model.RestUserRegistration; import com.wisemapping.security.JwtTokenUtil; import com.wisemapping.service.UserService; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -38,15 +34,8 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; -import static com.wisemapping.test.rest.RestHelper.createDummyUser; -import static org.hamcrest.Matchers.containsString; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, JwtAuthController.class}) diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java index 661fd86a..73fe8128 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java @@ -27,22 +27,20 @@ import com.wisemapping.rest.UserController; import com.wisemapping.rest.model.RestUser; import com.wisemapping.rest.model.RestUserRegistration; import com.wisemapping.service.UserService; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; import org.springframework.test.web.servlet.MockMvc; import static com.wisemapping.test.rest.RestHelper.createDummyUser; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; From 88d5f0df436efe5c4e6e51095ac77c186d1c42c9 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Tue, 6 Feb 2024 22:26:44 -0800 Subject: [PATCH 062/110] Renove http basic. --- .../config/rest/RestAppConfig.java | 2 +- .../config/rest/ServletConfig.java | 29 ------------------- .../wisemapping/dao/MindmapManagerImpl.java | 5 ++-- .../java/com/wisemapping/model/Mindmap.java | 11 +++---- 4 files changed, 7 insertions(+), 40 deletions(-) delete mode 100644 wise-api/src/main/java/com/wisemapping/config/rest/ServletConfig.java diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index 65546bd1..7ee683a9 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -54,7 +54,7 @@ public class RestAppConfig { })) .csrf(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - .httpBasic(withDefaults()) +// .httpBasic(withDefaults()) .build(); } } diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/ServletConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/ServletConfig.java deleted file mode 100644 index bd2cccb1..00000000 --- a/wise-api/src/main/java/com/wisemapping/config/rest/ServletConfig.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright [2022] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.wisemapping.config.rest; - -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ServletConfig implements WebServerFactoryCustomizer { - public void customize(ConfigurableServletWebServerFactory factory){ - factory.setPort(8081); - } -} \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java b/wise-api/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java index be680f03..a1f7c971 100644 --- a/wise-api/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java +++ b/wise-api/src/main/java/com/wisemapping/dao/MindmapManagerImpl.java @@ -124,17 +124,16 @@ public class MindmapManagerImpl @Override public Mindmap getMindmapByTitle(final String title, final User user) { - final Mindmap result; + final TypedQuery query = entityManager.createQuery("from com.wisemapping.model.Mindmap wisemapping where title=:title and creator=:creator", Mindmap.class); query.setParameter("title", title); query.setParameter("creator", user); List mindMaps = query.getResultList(); + Mindmap result = null; if (mindMaps != null && !mindMaps.isEmpty()) { result = mindMaps.get(0); - } else { - result = null; } return result; } diff --git a/wise-api/src/main/java/com/wisemapping/model/Mindmap.java b/wise-api/src/main/java/com/wisemapping/model/Mindmap.java index ea8787db..3c90eae5 100644 --- a/wise-api/src/main/java/com/wisemapping/model/Mindmap.java +++ b/wise-api/src/main/java/com/wisemapping/model/Mindmap.java @@ -311,13 +311,10 @@ public class Mindmap implements Serializable { } public static String getDefaultMindmapXml(@NotNull final String title) { - - final StringBuilder result = new StringBuilder(); - result.append(""); - result.append(""); - return result.toString(); + return "" + + ""; } static private String escapeXmlAttribute(String attValue) { From e3998ef3d430afddddf79cccda087741968f8df9 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Tue, 6 Feb 2024 23:04:25 -0800 Subject: [PATCH 063/110] Migrate to springboot emai. --- .../config/common/CommonConfig.java | 1 - .../config/rest/RestAppConfig.java | 2 +- .../wisemapping/service/MailerService.java | 13 ++--- .../wisemapping/service/NotifierFilter.java | 54 ------------------- wise-api/src/main/resources/application.yml | 32 ++++++----- .../resources/spring/wisemapping-mail.xml | 31 ----------- 6 files changed, 23 insertions(+), 110 deletions(-) delete mode 100644 wise-api/src/main/java/com/wisemapping/service/NotifierFilter.java delete mode 100755 wise-api/src/main/resources/spring/wisemapping-mail.xml diff --git a/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java index 52d113cb..f945cbdf 100644 --- a/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java @@ -12,6 +12,5 @@ import org.springframework.context.annotation.ImportResource; @ComponentScan(basePackageClasses = {AuthenticationProvider.class, MindmapServiceImpl.class, LabelManagerImpl.class, VelocityEngineUtils.class}) @Import({JPAConfig.class, SecurityConfig.class}) @EnableAutoConfiguration -@ImportResource(value = {"classpath:spring/wisemapping-mail.xml"}) public class CommonConfig { } diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index 7ee683a9..65546bd1 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -54,7 +54,7 @@ public class RestAppConfig { })) .csrf(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) -// .httpBasic(withDefaults()) + .httpBasic(withDefaults()) .build(); } } diff --git a/wise-api/src/main/java/com/wisemapping/service/MailerService.java b/wise-api/src/main/java/com/wisemapping/service/MailerService.java index d38d42ca..9e04da1c 100644 --- a/wise-api/src/main/java/com/wisemapping/service/MailerService.java +++ b/wise-api/src/main/java/com/wisemapping/service/MailerService.java @@ -38,21 +38,18 @@ public final class MailerService { //~ Instance fields ...................................................................................... -// @Autowired + @Autowired private JavaMailSender mailSender; @Autowired private VelocityEngineWrapper velocityEngineWrapper; - @Value("${mail.serverSendEmail}") + @Value("${app.mail.serverSendEmail}") private String serverFromEmail; - @Value("${mail.supportEmail}") + @Value("${app.mail.supportEmail}") private String supportEmail; - @Value("${mail.errorReporterEmail:}") - private String errorReporterEmail; - //~ Methods .............................................................................................. public String getServerSenderEmail() { @@ -86,8 +83,4 @@ public final class MailerService { public String getSupportEmail() { return supportEmail; } - - public String getErrorReporterEmail() { - return errorReporterEmail; - } } diff --git a/wise-api/src/main/java/com/wisemapping/service/NotifierFilter.java b/wise-api/src/main/java/com/wisemapping/service/NotifierFilter.java deleted file mode 100644 index d6f171a9..00000000 --- a/wise-api/src/main/java/com/wisemapping/service/NotifierFilter.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright [2022] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.wisemapping.service; - -import org.jetbrains.annotations.NotNull; -import org.springframework.util.DigestUtils; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; - -public class NotifierFilter { - public static final int MAX_CACHE_ENTRY = 500; - private final Map emailByMd5 = Collections.synchronizedMap(new LinkedHashMap() { - protected boolean removeEldestEntry(Map.Entry eldest) { - return size() > MAX_CACHE_ENTRY; - } - }); - - public boolean hasBeenSend(@NotNull final String email, @NotNull final Map model) { - - final StringBuilder buff = new StringBuilder(); - for (String key : model.keySet()) { - if (!key.equals("mapXML")) { - buff.append(key); - buff.append("="); - buff.append(model.get(key)); - } - } - - final String digest = DigestUtils.md5DigestAsHex(buff.toString().getBytes()); - boolean result = emailByMd5.containsKey(digest); - if (!result) { - emailByMd5.put(digest, email); - } - return result; - } - -} diff --git a/wise-api/src/main/resources/application.yml b/wise-api/src/main/resources/application.yml index b02c1c65..13c110ba 100755 --- a/wise-api/src/main/resources/application.yml +++ b/wise-api/src/main/resources/application.yml @@ -1,6 +1,17 @@ # SpringBoot Configuration ... spring: + mail: + host: smtp.example.com + port: 25 + username: setusername + password: setpassword + properties: + mail: + smtp: + connectiontimeout: 5000 + timeout: 3000 + writetimeout: 5000 output: ansi: enabled=always: @@ -38,13 +49,20 @@ logging: root: TRACE # Application Configuration. - app: jwt: secret: dlqxKAg685SaKhsQXIMeM=JWCw3bkl3Ei3Tb7LMlnd19oMd66burPNlJ0Po1qguyjgpakQTk2CN3 expirationMin: 10080 # One week admin: user: admin@wisemapping.org + mail: + serverSendEmail: root@localhost + supportEmail: root@localhost + + + + + google: ads: @@ -56,18 +74,6 @@ google: enabled: true secretKey: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe siteKey: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI -mail: - password: '' - serverSendEmail: root@localhost - smtp: - auth: false - host: localhost - port: 25 - quitwait: false - starttls: - enable: false - supportEmail: root@localhost - username: root security: oauth2: google: diff --git a/wise-api/src/main/resources/spring/wisemapping-mail.xml b/wise-api/src/main/resources/spring/wisemapping-mail.xml deleted file mode 100755 index 7a097fe9..00000000 --- a/wise-api/src/main/resources/spring/wisemapping-mail.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - ${mail.smtp.auth:false} - ${mail.smtp.starttls.enable:false} - ${mail.smtp.quitwait:true} - - - - - - - - - messages - - - - From 56c322fd3fbc853e5a265e2bb110ab633eb9151b Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Tue, 6 Feb 2024 23:43:52 -0800 Subject: [PATCH 064/110] Add redirect on expiration. --- .../main/java/com/wisemapping/config/rest/RestAppConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index 65546bd1..7ee683a9 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -54,7 +54,7 @@ public class RestAppConfig { })) .csrf(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - .httpBasic(withDefaults()) +// .httpBasic(withDefaults()) .build(); } } From 885de4e1c145fe1a7796f573c58aea903c71867e Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Wed, 7 Feb 2024 00:04:06 -0800 Subject: [PATCH 065/110] Fix login bug. --- .../filter/JwtAuthenticationFilter.java | 8 +- .../wisemapping/rest/MindmapController.java | 12 +- .../com/wisemapping/rest/UserController.java | 160 +++++++++--------- .../rest/model/RestMindmapMetadata.java | 47 +++++ wise-api/src/main/resources/application.yml | 3 + 5 files changed, 147 insertions(+), 83 deletions(-) create mode 100644 wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java diff --git a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java index c0695515..fe462d9d 100644 --- a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java +++ b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java @@ -11,8 +11,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; @@ -43,13 +45,13 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { if (email.isPresent() && jwtTokenUtil.validateJwtToken(token.get())) { // Is it an existing user ? - final UserDetails userDetails = userDetailsService.loadUserByUsername(email.get()); - if (userDetails != null) { + try { + final UserDetails userDetails = userDetailsService.loadUserByUsername(email.get()); final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities()); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authenticationToken); - } else { + } catch (UsernameNotFoundException e) { logger.trace("User " + email.get() + " could not be found"); } } diff --git a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java index f4784bc3..526c5fcb 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java @@ -69,7 +69,7 @@ public class MindmapController extends BaseController { @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") - @RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = {"application/json"}) + @RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = {"application/json"}) @ResponseBody public RestMindmap retrieve(@PathVariable int id) throws WiseMappingException { final User user = Utils.getUser(); @@ -77,6 +77,16 @@ public class MindmapController extends BaseController { return new RestMindmap(mindMap, user); } + @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") + @RequestMapping(method = RequestMethod.GET, value = "/{id}/metadata", produces = {"application/json"}) + @ResponseBody + public RestMindmap retrieveMetadata(@PathVariable int id) throws WiseMappingException { + final User user = Utils.getUser(); + + final Mindmap mindMap = findMindmapById(id); + return new RestMindmap(mindMap, user); + } + @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") @RequestMapping(method = RequestMethod.GET, value = "/", produces = {"application/json"}) public RestMindmapList retrieveList(@RequestParam(required = false) String q) { diff --git a/wise-api/src/main/java/com/wisemapping/rest/UserController.java b/wise-api/src/main/java/com/wisemapping/rest/UserController.java index 8e04eb4c..875719d9 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/UserController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/UserController.java @@ -51,100 +51,102 @@ import java.util.List; @RequestMapping("/api/restful/users") public class UserController extends BaseController { - @Qualifier("userService") - @Autowired - private UserService userService; + @Qualifier("userService") + @Autowired + private UserService userService; - @Autowired - private RecaptchaService captchaService; + @Autowired + private RecaptchaService captchaService; - @Qualifier("authenticationManager") - @Autowired - private AuthenticationManager authManager; + @Qualifier("authenticationManager") + @Autowired + private AuthenticationManager authManager; - @Value("${google.recaptcha2.enabled:false}") - private Boolean recatchaEnabled; + @Value("${google.recaptcha2.enabled:false}") + private Boolean recatchaEnabled; - @Value("${accounts.exclusion.domain:''}") - private String domainBanExclusion; + @Value("${app.accounts.exclusion.domain:''}") + private String domainBanExclusion; - private static final Logger logger = LogManager.getLogger(); - private static final String REAL_IP_ADDRESS_HEADER = "X-Real-IP"; + private static final Logger logger = LogManager.getLogger(); + private static final String REAL_IP_ADDRESS_HEADER = "X-Real-IP"; - @RequestMapping(method = RequestMethod.POST, value = "/", produces = { "application/json" }) - @ResponseStatus(value = HttpStatus.CREATED) - public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request, - @NotNull HttpServletResponse response) throws WiseMappingException, BindException { - logger.debug("Register new user:" + registration.getEmail()); + @RequestMapping(method = RequestMethod.POST, value = "/", produces = {"application/json"}) + @ResponseStatus(value = HttpStatus.CREATED) + public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request, + @NotNull HttpServletResponse response) throws WiseMappingException, BindException { + logger.debug("Register new user:" + registration.getEmail()); - if (registration.getPassword().length() > User.MAX_PASSWORD_LENGTH_SIZE) { - throw new PasswordTooLongException(); - } + if (registration.getPassword().length() > User.MAX_PASSWORD_LENGTH_SIZE) { + throw new PasswordTooLongException(); + } - // If tomcat is behind a reverse proxy, ip needs to be found in other header. - String remoteIp = request.getHeader(REAL_IP_ADDRESS_HEADER); - if (remoteIp == null || remoteIp.isEmpty()) { - remoteIp = request.getRemoteAddr(); - } - logger.debug("Remote address" + remoteIp); + // If tomcat is behind a reverse proxy, ip needs to be found in other header. + String remoteIp = request.getHeader(REAL_IP_ADDRESS_HEADER); + if (remoteIp == null || remoteIp.isEmpty()) { + remoteIp = request.getRemoteAddr(); + } + logger.debug("Remote address" + remoteIp); - verify(registration, remoteIp); + verify(registration, remoteIp); - final User user = new User(); - user.setEmail(registration.getEmail().trim()); - user.setFirstname(registration.getFirstname()); - user.setLastname(registration.getLastname()); - user.setPassword(registration.getPassword()); + final User user = new User(); + user.setEmail(registration.getEmail().trim()); + user.setFirstname(registration.getFirstname()); + user.setLastname(registration.getLastname()); + user.setPassword(registration.getPassword()); - user.setAuthenticationType(AuthenticationType.DATABASE); - userService.createUser(user, false, true); - response.setHeader("Location", "/api/restful/users/" + user.getId()); - } + user.setAuthenticationType(AuthenticationType.DATABASE); + userService.createUser(user, false, true); + response.setHeader("Location", "/api/restful/users/" + user.getId()); + response.setHeader("ResourceId", Integer.toString(user.getId())); - @RequestMapping(method = RequestMethod.PUT, value = "/resetPassword", produces = { "application/json" }) - @ResponseStatus(value = HttpStatus.OK) - public RestResetPasswordResponse resetPassword(@RequestParam String email) throws InvalidAuthSchemaException, EmailNotExistsException { - try { - return userService.resetPassword(email); - } catch (InvalidUserEmailException e) { - throw new EmailNotExistsException(e); - } - } + } - private void verify(@NotNull final RestUserRegistration registration, @NotNull String remoteAddress) - throws BindException { + @RequestMapping(method = RequestMethod.PUT, value = "/resetPassword", produces = {"application/json"}) + @ResponseStatus(value = HttpStatus.OK) + public RestResetPasswordResponse resetPassword(@RequestParam String email) throws InvalidAuthSchemaException, EmailNotExistsException { + try { + return userService.resetPassword(email); + } catch (InvalidUserEmailException e) { + throw new EmailNotExistsException(e); + } + } - final BindException errors = new RegistrationException(registration, "registration"); - final UserValidator validator = new UserValidator(); - validator.setUserService(userService); - validator.validate(registration, errors); + private void verify(@NotNull final RestUserRegistration registration, @NotNull String remoteAddress) + throws BindException { - // If captcha is enabled, generate it ... - if (recatchaEnabled) { - final String recaptcha = registration.getRecaptcha(); - if (recaptcha != null) { - final String reCaptchaResponse = captchaService.verifyRecaptcha(remoteAddress, recaptcha); - if (reCaptchaResponse != null && !reCaptchaResponse.isEmpty()) { - errors.rejectValue("recaptcha", reCaptchaResponse); - } - } else { - errors.rejectValue("recaptcha", Messages.CAPTCHA_LOADING_ERROR); - } - } else { - logger.warn("captchaEnabled is enabled.Recommend to enable it for production environments."); - } + final BindException errors = new RegistrationException(registration, "registration"); + final UserValidator validator = new UserValidator(); + validator.setUserService(userService); + validator.validate(registration, errors); - if (errors.hasErrors()) { - throw errors; - } + // If captcha is enabled, generate it ... + if (recatchaEnabled) { + final String recaptcha = registration.getRecaptcha(); + if (recaptcha != null) { + final String reCaptchaResponse = captchaService.verifyRecaptcha(remoteAddress, recaptcha); + if (reCaptchaResponse != null && !reCaptchaResponse.isEmpty()) { + errors.rejectValue("recaptcha", reCaptchaResponse); + } + } else { + errors.rejectValue("recaptcha", Messages.CAPTCHA_LOADING_ERROR); + } + } else { + logger.warn("captchaEnabled is enabled.Recommend to enable it for production environments."); + } - // Is excluded ?. - final List excludedDomains = Arrays.asList(domainBanExclusion.split(",")); - final String emailDomain = registration.getEmail().split("@")[1]; - if (excludedDomains.contains(emailDomain)) { - throw new IllegalArgumentException( - "Email is part of ban exclusion list due to abuse. Please, contact site admin if you think this is an error." - + emailDomain); - } - } + if (errors.hasErrors()) { + throw errors; + } + + // Is excluded ?. + final List excludedDomains = Arrays.asList(domainBanExclusion.split(",")); + final String emailDomain = registration.getEmail().split("@")[1]; + if (excludedDomains.contains(emailDomain)) { + throw new IllegalArgumentException( + "Email is part of ban exclusion list due to abuse. Please, contact site admin if you think this is an error." + + emailDomain); + } + } } diff --git a/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java b/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java new file mode 100644 index 00000000..63158ce3 --- /dev/null +++ b/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java @@ -0,0 +1,47 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.wisemapping.rest.model; + + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.wisemapping.exceptions.InvalidMindmapException; +import com.wisemapping.exceptions.WiseMappingException; +import com.wisemapping.model.*; +import com.wisemapping.util.TimeUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.Calendar; + +@JsonAutoDetect( + fieldVisibility = JsonAutoDetect.Visibility.NONE, + setterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY, + isGetterVisibility = JsonAutoDetect.Visibility.NONE, + getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY +) +@JsonIgnoreProperties(ignoreUnknown = true) +public class RestMindmapMetadata { + + public RestMindmapMetadata() throws WiseMappingException { + } + +} diff --git a/wise-api/src/main/resources/application.yml b/wise-api/src/main/resources/application.yml index 13c110ba..12e87cc1 100755 --- a/wise-api/src/main/resources/application.yml +++ b/wise-api/src/main/resources/application.yml @@ -58,6 +58,9 @@ app: mail: serverSendEmail: root@localhost supportEmail: root@localhost +# accounts: +# exclusion: +# domain: From 05c2e545aea57408824cc9cff7d940cabdc8b304 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Wed, 7 Feb 2024 18:44:33 -0800 Subject: [PATCH 066/110] Add map metadata. --- wise-api/pom.xml | 3 +- .../java/com/wisemapping/Application.java | 1 - .../config/mvc/InterceptorsConfig.java | 43 -------- .../wisemapping/config/mvc/MvcAppConfig.java | 49 --------- .../config/mvc/MvcSecurityConfig.java | 100 ------------------ .../config/rest/RestAppConfig.java | 2 +- .../wisemapping/rest/MindmapController.java | 39 ++++--- .../rest/model/RestMindmapMetadata.java | 51 +++++++-- .../com/wisemapping/view/MindMapBean.java | 4 - .../src/main/resources/public/favicon.ico | Bin 1150 -> 0 bytes .../src/main/resources/public/favicon.png | Bin 34875 -> 0 bytes wise-api/src/main/resources/public/index.html | 6 -- .../test/rest/RestMindmapControllerTest.java | 86 +++++++++------ 13 files changed, 124 insertions(+), 260 deletions(-) delete mode 100644 wise-api/src/main/java/com/wisemapping/config/mvc/InterceptorsConfig.java delete mode 100644 wise-api/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java delete mode 100644 wise-api/src/main/java/com/wisemapping/config/mvc/MvcSecurityConfig.java delete mode 100644 wise-api/src/main/resources/public/favicon.ico delete mode 100644 wise-api/src/main/resources/public/favicon.png delete mode 100644 wise-api/src/main/resources/public/index.html diff --git a/wise-api/pom.xml b/wise-api/pom.xml index aecf4ca6..30c6510b 100644 --- a/wise-api/pom.xml +++ b/wise-api/pom.xml @@ -4,7 +4,7 @@ org.springframework.boot spring-boot-starter-parent - 3.2.1 + 3.2.2 org.wisemapping @@ -199,7 +199,6 @@ - org.apache.maven.plugins diff --git a/wise-api/src/main/java/com/wisemapping/Application.java b/wise-api/src/main/java/com/wisemapping/Application.java index 5ac5f722..5283b2f5 100644 --- a/wise-api/src/main/java/com/wisemapping/Application.java +++ b/wise-api/src/main/java/com/wisemapping/Application.java @@ -1,7 +1,6 @@ package com.wisemapping; import com.wisemapping.config.common.CommonConfig; -import com.wisemapping.config.mvc.MvcAppConfig; import com.wisemapping.config.rest.RestAppConfig; import org.springframework.boot.WebApplicationType; import org.springframework.boot.builder.SpringApplicationBuilder; diff --git a/wise-api/src/main/java/com/wisemapping/config/mvc/InterceptorsConfig.java b/wise-api/src/main/java/com/wisemapping/config/mvc/InterceptorsConfig.java deleted file mode 100644 index 400a68e5..00000000 --- a/wise-api/src/main/java/com/wisemapping/config/mvc/InterceptorsConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright [2022] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.wisemapping.config.mvc; - -import com.wisemapping.filter.RequestPropertiesInterceptor; -import com.wisemapping.filter.UserLocaleInterceptor; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -//@Configuration -//@ComponentScan(basePackageClasses = UserLocaleInterceptor.class) -public class InterceptorsConfig implements WebMvcConfigurer { - @Autowired - private UserLocaleInterceptor userLocaleInterceptor; - - @Autowired - private RequestPropertiesInterceptor requestPropertiesInterceptor; - - @Override - public void addInterceptors(@NotNull final InterceptorRegistry registry) { - registry.addInterceptor(userLocaleInterceptor); - registry.addInterceptor(requestPropertiesInterceptor); - } -} \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java deleted file mode 100644 index c17f0b51..00000000 --- a/wise-api/src/main/java/com/wisemapping/config/mvc/MvcAppConfig.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.wisemapping.config.mvc; - -import com.wisemapping.webmvc.MvcMindmapController; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.web.servlet.HandlerExceptionResolver; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; - - -//@SpringBootApplication -//@Import({MvcMindmapController.class, MvcSecurityConfig.class}) -//@EnableWebMvc -public class MvcAppConfig implements WebMvcConfigurer { - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry - .addResourceHandler("/**") - .addResourceLocations("classpath:/public/"); - } - - @Bean - public ViewResolver viewResolver() { - InternalResourceViewResolver resolver = new InternalResourceViewResolver(); - resolver.setPrefix("/WEB-INF/jsp/"); - resolver.setSuffix(".jsp"); - resolver.setViewClass(JstlView.class); - return resolver; - } - - @Bean - HandlerExceptionResolver errorHandler() { - final SimpleMappingExceptionResolver result = new SimpleMappingExceptionResolver(); - - //mapping status code with view response. - result.addStatusCode("reactInclude", 403); - - //setting default error view - result.setDefaultErrorView("reactInclude"); - result.setDefaultStatusCode(500); - return result; - } -} \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/config/mvc/MvcSecurityConfig.java b/wise-api/src/main/java/com/wisemapping/config/mvc/MvcSecurityConfig.java deleted file mode 100644 index cb236793..00000000 --- a/wise-api/src/main/java/com/wisemapping/config/mvc/MvcSecurityConfig.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.wisemapping.config.mvc; - -import org.jetbrains.annotations.NotNull; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -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.configurers.AbstractHttpConfigurer; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; -import org.springframework.web.servlet.handler.HandlerMappingIntrospector; - -@Configuration -@EnableWebSecurity -public class MvcSecurityConfig { - @Bean - @Order(1) - public SecurityFilterChain embeddedDisabledXOrigin(@NotNull final HttpSecurity http, @NotNull final MvcRequestMatcher.Builder mvc) throws Exception { - http - .securityMatchers((matchers) -> - matchers.requestMatchers(mvc.pattern("/c/maps/*/embed"))) - .authorizeHttpRequests( - (auth) -> auth.requestMatchers(mvc.pattern(("/c/maps/*/embed"))).permitAll()) - .headers((header -> header.frameOptions() - .disable() - )) - .csrf(AbstractHttpConfigurer::disable); - - return http.build(); - } - - @Bean - MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) { - return new MvcRequestMatcher.Builder(introspector); - } - - @Bean - @Order(2) - public SecurityFilterChain mvcFilterChain(@NotNull final HttpSecurity http, @NotNull final MvcRequestMatcher.Builder mvc) throws Exception { - http - .securityMatchers((matchers) -> - matchers.requestMatchers(mvc.pattern("/c/**"))) - .authorizeHttpRequests( - (auth) -> - auth - .requestMatchers(mvc.pattern("/c/login")).permitAll() - .requestMatchers(mvc.pattern("/c/logout")).permitAll() - .requestMatchers(mvc.pattern("/c/registration")).permitAll() - .requestMatchers(mvc.pattern("/c/registration-success")).permitAll() - .requestMatchers(mvc.pattern("/c/registration-google")).permitAll() - - .requestMatchers(mvc.pattern("/c/forgot-password")).permitAll() - .requestMatchers(mvc.pattern("/c/forgot-password-success")).permitAll() - .requestMatchers(mvc.pattern("/c/maps/*/try")).permitAll() - .requestMatchers(mvc.pattern("/c/maps/*/public")).permitAll() - .requestMatchers(mvc.pattern("/c/**")).hasAnyRole("USER", "ADMIN") - .anyRequest().authenticated()) - .formLogin((loginForm) -> - loginForm.loginPage("/c/login") - .loginProcessingUrl("/c/perform-login") - .defaultSuccessUrl("/c/maps/") - .failureUrl("/c/login?login_error=2")) - .logout((logout) -> - logout - .logoutUrl("/c/logout") - .logoutSuccessUrl("/c/login") - .invalidateHttpSession(true) - .deleteCookies("JSESSIONID") - .permitAll() - ).rememberMe(remember -> - remember - .tokenValiditySeconds(2419200) - .rememberMeParameter("remember-me" - ) - ).headers((header -> header.frameOptions() - .disable() - )) - .csrf((csrf) -> - csrf.ignoringRequestMatchers(mvc.pattern("/c/logout"))); - - return http.build(); - } - - @Bean - @Order(3) - public SecurityFilterChain shareResourcesFilterChain(@NotNull final HttpSecurity http, @NotNull final MvcRequestMatcher.Builder mvc) throws Exception { - return http.authorizeHttpRequests( - (auth) -> - auth.requestMatchers(mvc.pattern("/static/**")).permitAll(). - requestMatchers(mvc.pattern("/css/**")).permitAll(). - requestMatchers(mvc.pattern("/js/**")).permitAll(). - // @todo: Why this is required ... - requestMatchers(mvc.pattern("/WEB-INF/jsp/*.jsp")).permitAll(). - requestMatchers(mvc.pattern("/images/**")).permitAll(). - requestMatchers(mvc.pattern("/*")).permitAll() - - ).build(); - } -} diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index 7ee683a9..65546bd1 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -54,7 +54,7 @@ public class RestAppConfig { })) .csrf(AbstractHttpConfigurer::disable) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) -// .httpBasic(withDefaults()) + .httpBasic(withDefaults()) .build(); } } diff --git a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java index 526c5fcb..b1d1df7d 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java @@ -24,6 +24,7 @@ import com.wisemapping.rest.model.*; import com.wisemapping.security.Utils; import com.wisemapping.service.*; import com.wisemapping.validator.MapInfoValidator; +import com.wisemapping.view.MindMapBean; import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.validator.routines.EmailValidator; import org.apache.logging.log4j.LogManager; @@ -32,6 +33,7 @@ import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -72,7 +74,7 @@ public class MindmapController extends BaseController { @RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = {"application/json"}) @ResponseBody public RestMindmap retrieve(@PathVariable int id) throws WiseMappingException { - final User user = Utils.getUser(); + final User user = Utils.getUser(true); final Mindmap mindMap = findMindmapById(id); return new RestMindmap(mindMap, user); } @@ -80,17 +82,28 @@ public class MindmapController extends BaseController { @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") @RequestMapping(method = RequestMethod.GET, value = "/{id}/metadata", produces = {"application/json"}) @ResponseBody - public RestMindmap retrieveMetadata(@PathVariable int id) throws WiseMappingException { - final User user = Utils.getUser(); - - final Mindmap mindMap = findMindmapById(id); - return new RestMindmap(mindMap, user); + public RestMindmapMetadata retrieveMetadata(@PathVariable int id) throws WiseMappingException { + final User user = Utils.getUser(true); + final Mindmap mindmap = findMindmapById(id); + final MindMapBean mindMapBean = new MindMapBean(mindmap, user); + + // Is the mindmap locked ?. + boolean isLocked = false; + final LockManager lockManager = this.mindmapService.getLockManager(); + String lockFullName = null; + if (lockManager.isLocked(mindmap) && !lockManager.isLockedBy(mindmap, user)) { + final LockInfo lockInfo = lockManager.getLockInfo(mindmap); + isLocked = true; + lockFullName = lockInfo.getUser().getFullName(); + } + + return new RestMindmapMetadata(mindmap.getTitle(), mindMapBean.getProperties(), isLocked, lockFullName); } @PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')") @RequestMapping(method = RequestMethod.GET, value = "/", produces = {"application/json"}) public RestMindmapList retrieveList(@RequestParam(required = false) String q) { - final User user = Utils.getUser(); + final User user = Utils.getUser(true); final MindmapFilter filter = MindmapFilter.parse(q); List mindmaps = mindmapService.findMindmapsByUser(user); @@ -119,7 +132,7 @@ public class MindmapController extends BaseController { public void updateDocument(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws WiseMappingException, IOException { final Mindmap mindmap = findMindmapById(id); - final User user = Utils.getUser(); + final User user = Utils.getUser(true); // Validate arguments ... final String properties = restMindmap.getProperties(); @@ -148,7 +161,7 @@ public class MindmapController extends BaseController { @ResponseStatus(value = HttpStatus.NO_CONTENT) public void updateRevertMindmap(@PathVariable int id, @PathVariable String hid) throws WiseMappingException, IOException { final Mindmap mindmap = findMindmapById(id); - final User user = Utils.getUser(); + final User user = Utils.getUser(true); if (LATEST_HISTORY_REVISION.equals(hid)) { // Revert to the latest stored version ... @@ -178,7 +191,7 @@ public class MindmapController extends BaseController { @ResponseBody public void updateDocument(@PathVariable int id, @RequestBody String xmlDoc) throws WiseMappingException { final Mindmap mindmap = findMindmapById(id); - final User user = Utils.getUser(); + final User user = Utils.getUser(true); mindmap.setXmlStr(xmlDoc); saveMindmapDocument(false, mindmap, user); @@ -203,7 +216,7 @@ public class MindmapController extends BaseController { public void updateProperties(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws IOException, WiseMappingException { final Mindmap mindmap = findMindmapById(id); - final User user = Utils.getUser(); + final User user = Utils.getUser(true); final String xml = restMindmap.getXml(); if (xml != null && !xml.isEmpty()) { @@ -239,7 +252,7 @@ public class MindmapController extends BaseController { @NotNull private Mindmap findMindmapById(int id) throws MapCouldNotFoundException, AccessDeniedSecurityException { // Has enough permissions ? - final User user = Utils.getUser(); + final User user = Utils.getUser(true); if (!mindmapService.hasPermissions(user, id, CollaborationRole.VIEWER)) { throw new AccessDeniedSecurityException(id, user); } @@ -258,7 +271,7 @@ public class MindmapController extends BaseController { public void updateTitle(@RequestBody String title, @PathVariable int id) throws WiseMappingException { final Mindmap mindMap = findMindmapById(id); - final User user = Utils.getUser(); + final User user = Utils.getUser(true); // Is there a map with the same name ? if (mindmapService.getMindmapByTitle(title, user) != null) { diff --git a/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java b/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java index 63158ce3..050cf876 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java +++ b/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java @@ -20,18 +20,10 @@ package com.wisemapping.rest.model; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.wisemapping.exceptions.InvalidMindmapException; -import com.wisemapping.exceptions.WiseMappingException; -import com.wisemapping.model.*; -import com.wisemapping.util.TimeUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; -import java.util.Calendar; - @JsonAutoDetect( fieldVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY, @@ -40,8 +32,49 @@ import java.util.Calendar; ) @JsonIgnoreProperties(ignoreUnknown = true) public class RestMindmapMetadata { + private String jsonProps; + private boolean locked; + private String title; - public RestMindmapMetadata() throws WiseMappingException { + public String getJsonProps() { + return jsonProps; + } + + public void setJsonProps(String jsonProps) { + this.jsonProps = jsonProps; + } + + public boolean isLocked() { + return locked; + } + + public void setLocked(boolean locked) { + this.locked = locked; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getLockFullName() { + return lockFullName; + } + + public void setLockFullName(String lockFullName) { + this.lockFullName = lockFullName; + } + + private String lockFullName; + + public RestMindmapMetadata(@NotNull String title, @NotNull String jsonProps, boolean locked, @Nullable String lockFullName) { + this.jsonProps = jsonProps; + this.title = title; + this.locked = locked; + this.lockFullName = lockFullName; } } diff --git a/wise-api/src/main/java/com/wisemapping/view/MindMapBean.java b/wise-api/src/main/java/com/wisemapping/view/MindMapBean.java index 4b806f3a..b62da707 100644 --- a/wise-api/src/main/java/com/wisemapping/view/MindMapBean.java +++ b/wise-api/src/main/java/com/wisemapping/view/MindMapBean.java @@ -127,10 +127,6 @@ public class MindMapBean { mindmap.setDescription(d); } - public String getXmlAsJsLiteral() throws IOException { - return this.mindmap.getXmlAsJsLiteral(); - } - public String getProperties() throws WiseMappingException { String result = null; diff --git a/wise-api/src/main/resources/public/favicon.ico b/wise-api/src/main/resources/public/favicon.ico deleted file mode 100644 index 955c5116c3c50060440fc49510674f5e6e564ac3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmcIjT}V@57=Cm%olBdQGn-3|qz0A6D5Q)s?H94NmBdCZ%FJ}IH6aYM)Q!a#)36cTlNd(YVoVNIwa?YXtQ- zhLF0joCTzRAtJ#%X#rLj+(mu!B>KJ+dM5~$E8mczZeo5m;^TiOBSntpG}jKJ<0GLz z%%BKfOc9zM6LuS)At_l4^@>=HEWVUP*8&<0Sgo|K+(alfGmg@l14c2Xw{h-}Vd}VkN5HHr_Akp!ck>zK zjQNlx?1j<(1>QlzlQDk(Q9}EBMlkAgtnm>cztF?=Dn_cvV-sC*NJ}q+p=tn)4@2+` z5qid%8`Y_A9*4H*7T2mFO`7Gz?x|^lp9Q7r1U3}6prqV~Z8|SBS|?=k63)qD34ip2 pK@(<{|Ju1*JY5K1h+r}s7+e5!Co&{}BktF}LT;36W|$*ze*j~O6XO5? diff --git a/wise-api/src/main/resources/public/favicon.png b/wise-api/src/main/resources/public/favicon.png deleted file mode 100644 index bb62808d994add45030bb41a6891c31eda51e96a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34875 zcmeFY_gj<67dIS0VO_8SAd!}!G*OBX0jW`uB30=SlHjryM0yhtLX#pw zq)Uy+DiBKO9il?$0ZBqhNO|x0eE0ba-XEXq(hG(;XU>_KQ$BNM?xf{{^-ut^h1A zzMB|ay%X|wbvp3vJD2I54VCGNfHb8WH-eRVoM|5o7t zt-$|JE1;VBUKQ<Yx}M;++~S)B*jp1|DE~r zZtL_CRd1J9t-FNNd5)uBYTTbSaF6gRnir*< z=+eJooX~te)2JPCbACVhT0DOM(R(%cHoTbhi~cIbQ7f4b;hI|9;ayS!_N9+}jW2wN z`-b+F*bH!{CMjy$SeJLtP>U4!6ZF{iAowFoDxCw^rT)|io+)Mb(kCRoh&P0h*>DYD z=N4`azG^$4X#=xO*ZQrhvMp60=%#gTv6PIo$d`%Mk3o7Lr2nb{mmX-r8Mo8-trfqu z8duYjd3|>`{VAWLW4~S%G6@W8z-tFi}0G=CfD>km>k;~H8s z@hABTN&H(_^1(_|OY0!3Mt;r>BJl`Zv!L5_tG=MpGN4Hn!4Ho^V6$V=>m_h?EvK_K zsILxNrw%o|*G>MlL<~*w&YL|N$0sUqvV&Q zPeiAP<;|W-{XIZHkK=fmpJjlQUnSVC?*JDM?9ji&SEu+B5gk)Xq2|r5uzd}=SO2tY zg(!mW94t}#EjjrX)hayG=0bEVdEE_?oFhGyE&JHs1yB6>n^kCtl~Q${^n(0LU$z)M zIloN2kg`{wFHx>?IDhuXL$D1-ocTgJ#|>|Nq0CFtNteHuB`;E=V#yM5@7XqU5Z8z( z8&uBs{VDXk*#)hdg@Ee-yT|Nvs|&^9muX<7&!0%L6#~<@+WC#Lse|4!LvqM zX!g6yzFPu9?gwjdLc^G2>Pi6Pnaf@^c-lzIfc>tAFF-jivM;B87$bLQxBeE@O}_>Q z<_~h?!&b`lgiUa}5%<1;yCd+|VT{q8T}=el&5$o%IQRaKPL7_8?_Ydd7yh`}mbCly z+aS~EX`7<|3*b)$Q64ReJ7&C_34~6O#h!IV=pBte`6CC`*aomiwy>wM`rwO~oXVtZ zY!&!wp$opAm$z;?!jue-;L=8k)cy@Q0pRZ?Ws`-f?`fDh-ys3vfl*vn_`XM=G zTg@t3PX{?(=s+#jdaY#j5HR}f{TiVz3&cetFuu^izCT(lH5)5U`3r3}LrbA6l4IC0 z8hWy*;!2duGGFzKf+a{`WA9Qn5A z5kFEk<-kPE`KAik^^cx!zvIeZtaG{2ZKLc*_bg2hyL?;9@76p+yhb-*&V50oB2N<~ zx{PdtpDC0o9d${!Fkt>Gh?vimCB~=cnQ8}ec|MD+D(A&tyb!*Tc;?Zej1s@Ql$s9m zAA@s+B?l*?yKSU9(xNLnml3tLD#Y?kgYn=}g%{MnC_B1&Z!56L`wvF@Q7RDS@Uui| zH^X|~7lk;-6BMRremFB#0SP%u$?8X7Xzs~m9Wjc9b3S{vMuAc)wgC4vU`}=+FuZ39 zaI7j3Ec1$1hRSQgppq+~2BFK#3ScJ*${IayD%>bJLEfmIQLL~a^%o_%IbW*TGdZ$0 zx^m$dB53L&@mEd0*T);lF5+>j?H`zt zX}H%;s9djnlI$E5?bn%rSko$+?c-+c=Cgl1i-PAs8?i0NC~k4V?5jV1bmch&`z5Pw z$N7EMKs?7Eb@^&xlYt_v{8S8{Z>`RyLO}hrkZbnA+%VP>6K9VkF7RD!3{keA^ zenz)chVl&=QhkfUAa0+=R^5Q7dsQmjR5|8SB$^*S|5;(%@i=92+lWaRrGxX;W07z% z%Ci+MnTH{Zv54nof4P*8)7n)yYtM)+DJA?(@*cmDQmTl3&F(oT_Gr08%gMWLvJla$ zeTEpBW)QmYlpT4thf2W3(FV*AK36Ui5sgOU?!yXnQaXGl{o(o@b5YVhU|t@Xspa7p zw47v9noqnlAGDBkp}fmmy{tq0YHSe7c%=XjSK#GbN0l@`*chJ7oAPr_o;5ZY5ARXf zPs+q%``p&8%}cta_zu>2EG||=zge7_X%U7%i8@eMc5CpiqcUr$=wFf9L)?qMc2W@L z6N-RWQONM2vaLaU{&`D&Jh02#t0->Gm8U^7P4%ez*flmQ(*btL>oJ}1zSe@BT}8yV znM0JR$b7FRyW~ejorLzqe&~6TfA}GwR#OpI!q%ce(_Xucf6ZSdm?dkIVrfanbgMGrv7}XV+|@GX-bFbxm9hInDFvGSKu$i!IvV zEibW!PCP7a#?Ts)@>eSilMQu@bNY3V;}-ytLm$m7H4AB+4zf;d&55Gu%2p!6d|aN` zmS)Io+s}NV>>l7dElx>Q%ai)#-L9xqweI{aw7T*Uu>U2wS_QPS4zg11yZYw_<9=DO zqrY^uRf)WoWbB*2UAH4e0DF=r{?InG4eey_HuX%~+sXqXlP6kIpr^6^W7dUlPXnHt z=kUZdIn6hUh6jx0X5TV~bvJoeWp(FVkGyy0>e$HZTlfE%nBG4c*c9}bd6u^DLW90e>>wrrv9mzHdv`J9ishE@M`eC2eA$yf z6=)8`piJy{frf2j83N{iFL^kv2M3+#Kq{u)ImS<0o1T)^*)Q3m$S(WGYYHM>VlE6r z1Xo>ycTb36Mx_dhOUt;7-C)v9GIzWwtHc9*K_(vM#FPX=tLGzq@mGHT_9A2&Rf%w? z9{6VvXBG&3M z@IVtUOr5w{WH9b?H+iY32N!8Kwn#kBm(yTZuPR4_K2dfXewWXWyJ^0?@YkSF%w|Bc zcJHf7z-L@>XR$sWS9!&6k?EKD8|*!Jr}upmgqc~FTCw&Dap8&*(Po_p4*wLEPCmd#aQVLeo6&_f^({Eqtm_mfb0l}>v(`M#UYOdMO(YH$pQGIehc1KE!brGb+2wj>7p55B6L z`pNY76noE6y7!zv_}?S%!%xwmx6E?4%Be})v9xblOv#{#r@t1DBDN%CT%Iq{7N+EA zVJ@?L>hI%yIy+T%eIzRNcoi5%zi*eJH>?KV5V zeuXsYqm*rA2RT4UJ#l>sLiuzU@w_`3ZUg;9FlrA|1blixHAO@gYdQ4M+DVldC~q9f zOJSP<_-3~=AJMCGk|^j;Ax(?=1W=NI-Bf=$JY&Od1mMNxf=%n!ehcGFNskCudgDT# zL-@mFiwkezY0!_zJ6rty5%Ad{>Lw7FkFMK)IO@`UmMQ5T;ksRymj7Dk67dy|h?|rg z>q)5x%=QuJJ;$@HF@f;o(G_j)zbH$dG-x-dY;lWZVC(jbUEgxG+3|PKW0mYxtTW`w z75!MPvPw?#A(Ewpsw4Zw4adD=*!6^~j@IcKz#7QqPM?PZOJ>&g1~Z{xyedUm$)`cv zK-9%flF|76NcLuqK(pQWNr03!_BLhZG*)f!;=I%m%3O0^xUVU9UOeJ=;&*DJkG>EN zFamaAczi3R4giFMhmNJI5bH&Znam_+rXvWpRvK)m8PKjUXr4uIRgW(^ulNiI>R?9z zRir-u$asJ#zamG35Z(~#_vQqzzmE0$lKtD&MIRl)zLz=I24Ka!uaUs< zaGdrzV&7i+Xx_sb8;&`j?A;_(EBnv4%^TM%mIn}PFcmC)pI$i`dy1GYVvrvCoLzIS ze}9S#kPm7edhfm>e4US@jnC$>7h>3E@}QXft>w>=btGib5l&O3{`JIy)Dmyx26XTM zqIXP%xSribekj=Y2}r;$llPe`)_H@#K$p?{fhGuxO}biG%YAzEPwQV4JeAT2&(GH9 zt9k;16n;=fZq&62OXI_dGX{cvP34-Wi1Noekb_5tWR5i1@kvVfBr~rNGEM5(!9Vmo zi#g$|3{GD66-TZFw1azhTn*UIw$UK`j(u2#0yI07fY_6Bxj7J-EL7WrTtD&_0?hut zXQ>UlN6V6rr)i_&bm$9Eb⋙bme9PbA@~om7|ITWIbPQ>L8yvkU@QJ$edrGLnA@e zxCy$z{F}>IWhn#lpQOF>;*$!0r;D_LOH2*4#;LXn^8o?1cJcv$J*XQ8<)FQd!#{(`PiyFB@HZh zLi73sK%n~fvb#*HITf~$$J#g_T60|wf>=MN%6 zzg7rqM=h+V%)Pe8@j+mFWWqFP;=cqc`g9OJx@uT4VbBQxohMsvcOv6N#<#4h;^S>K_-!4D;Qx- zdm)~;+U&xWfP>hF^%94UDW70Q`w;AaT;+VBlYB-%ue4#VgT09X?Z`#|VM0=Z8SPD& z@QP7b*NG=w0!G*d0QvI^ZwOo4YQNQd7;VHoJ&BK%Ody;Pj0mF58s~XcIdNrjaLnH$ z*j=QFk7Cs52M|7*vRJV_AnNiEnzk*(>4pfLF;VVsN+1+(We%rB(U!fLk`R!4aB!9w zA9QaEb2|7WX47vI2yeDBIkmC0q6(&@3@E2<)X2~__$yoY8k}YfGP!N3afT+|kMU>r zGc%mAOtVUbN@JL z;_<35hHY4d^dexAaj;ZEt^jD6{%j>ri5|t)HGpsMrRYOl=2TKSKfhDy&`TgaGUr#W zf+t!FtI}`rdo4e@s3dZJGB`A-3h48{yHtOK22u@c@xR{3oJ%zE4wInaC(O)apd9RK zg9&#g4;S8&hJFKp?vYVh?ESY7^Lu;9#UK!;bgQamRo4ivS(e5Dx`k$h5(p>FD~s@* zVLDS$b<$!`FP6}CQoTblE*en!I`0NcSY zjJSeVOi~@xi54te!gcncb^G) zuWBWY(ltr^R&$q<)q(shN8H8F`AUHz=C`I6Xxr*Z-($75P>E;0s;4ZR#{S4qAYkOM zZ6Hwf^LBhUdD8Unn=9ixCW#Y`lCs#=3wqtFRVY2Yt0R$a``88p!{&l zEP2$IL_P@ul|34&XQHyA7)~x(4M9(V5~0T+ztokxT*XiB2S5=cL0u=9sO%_)k;`?* z#;Yc`?W^xms2#{0)+%>D9l8gkhuQ%$2?`e#V2`%HW^!9wU5+MR2y5J^X2*a)eNGqP za#*l>LTsr&Qo+RIM{hKHZwcvwrYcqlP`!u_?ji3t`)9&J7h2+v1qfP$;@Dq{Nicss z?iVnqx=wAYi!5gLkFU*qnLiHb&$TWF4jkfnFijU6doKi(Ge0&>-!>BaksSt&PAnL4 zpCFEPAR}0FJGwOSFi=GK!5J7fPW`ZXY49Mx&Ml8-KP$3`ow$sBDgq?GZ2P(O6uB=W zf$LIdP0S_}5(wWJow?fcDyx7Kk7GD&T}ucjr}FN!_I2QJUW1_UPGeh3CIu$vRTe>@ zW`5aA!(JAnLse7COL(GihRS zyD9)Xr*biH5G>B3~hUU}MqyuQre=lz#KdRVQnQMRr% z#C!NfbK#kit6C>%;_(exl@?q^TiomepC^OF56|AJz;DiM$C{7p1aC7W-0$&fo!3f5R0 zTm!}#2udK_8*(XJ%5Mty=l*>Fbn$q(t|pc@EaJRdEtGObG;GkO6 ze-k^civ^E}6m7f6o;Q)0x&TPYyHK>AMgR$c9*%`gvzzZ`ah+_-EE*92tf}^yQ#lei z?lQ}MCJs8;WdVt<9Li&&Dz$X`>y%5*Ji5rw_b;8wsvjnkVQGY4f}n@2FExn5?DJS( z>mp~?Clx@6d+mnYFMXx9uCHmtGUomZAU)YnKZe*G+br%a+d|(-OOpY;>VN=K;`n}j z{F;tDHg_+`{fzu-0>QX+kb|DgyOAiIhdPbDx;X51umgEd03^|0+eX{=2-Nx*w|mFr zHoP`?PGwK?1YjD^j@}E$a&IU5PK!|zy0lxKqs9@4UagD7D3p<=Uz!5S=djDau85$q zlf+}5hU1S@6eK^;TCwF)z{xn@t3D_>OXC9Rj95K5w?4i6cydp05pXv2d^o29(&eA>@#JhmjvzIE3%^&$H>h^k&|Jvb3{;uq332ORi>0*7}53Zdu zk*KbH&5k121i#H9#0!>D`8DeHQUr#1C;3vEf#$;(3ei0{IM3|EqoP>gfc?7+15~S- zv-=U;%`k4Du&@OcsNMJ@q+9IM75ORhPKu2z_UC&4(@Ba-j^4_9jv{k#)Ic-5Na3c^ z&<1{KoIaz+KVg=t3~rb{#m^k2aBOIJ-HRVRNb)5dF9j60M4viY3`}=zwFCDHRXy|o zfuVbG1^=v$B{Yp~G%{zm7ei`0l+;YeOMv z22Pv@6dEZy&l6)Nq2u^xl^=UDkW^%=%%@MY=h!v)O%hNlW{+Hd-Yw+y*`q`EIytfU$ z?P9y0$Y4_TUHvA@8Ewe8K*O{Vg1i4>DZeP((7)V&GN4p;?OCRr&HSRgdT5>8&}l*ZT+W0|5VBDjdw-9FJ@vlzw$mY(7?;WQO>~SaaBH*Lgh=+C%7R~r zU}d3iaoPRR1glh0pjZgS286#mj{^9+;(C#Xo_^a*69=k3>{yXOGhHk0+pj!m*K0)3 z_!XjJoe^NNOy|9e)50;ls*=oWiR%48DM5_6XV^(IrTLIx%o1=5^Sb^FvCuOl51XIq zc|G}XrXiE2jF`cm#jb+Hwg!64E)^ZzZ*m)FUqT~w;Qp2WbUz#@0zNzBu2eJHJ1nzS z_tg#|N0;Ok-rhC(d|%rr6cv!nYf6BpMyxqLzRL~oj~3BS99l3kS-JqbYl)F z^}A7O7&+3n9wq_;MaWe>Ph3QL{@2(jaqrs#Djoo^0F^!102;6U zYy5EU1I*-qJuN`v^?!|C_rBVw{~9Cieb0^mH`*nAb@$BwhQ1W2?!NMWdu-L+75{7e zBJ_V2jbZQSzcDKNF5dsS=O|PB51?V!I@$kuSjIda{S;{B9Bq;iok1mF6ZnmB-J_y2 zcv;?QU=n&&jZldu;MUbp5SWo`u)cZ--uS=96ZH_%|LyTm56SRodVFHse{IFG|JV58{!8QkHr~7cO8u{~8r;7}G>W}{FP~>M zv;PcmWg@;GXk-jq_MhP>&{U2A4fRs{Jd?0<|26#cO&V1GYv|{hG^qa9D9bm|I`v;8 zCEsL1m!@K!?)LO6@mXEm-kg0d_*1i)K(u#*{6zsHU*2xHk-szZ=68&zb<*3f+qBh6 zC1Ah;7oSv)#$T9^mV0z}4*5ZKd@d;sp~5ZH;bsZyiPh7i38qN>28o7y{8~0`9ZCZ? zg-?;4V*NG_BV4o2VLt@ec|5BbSeFH{*1Ac$sV&a~`qlaS5qHOVJ?IEr5F}ZAOEyACIglK1c-~nr9ZC+1% z%DB2mk1XZiN?lqp?#ZJY@=xQD%A336voUo42oix!UfMnaLRZnR78T(kkmF)zBR3PU z{X~qsQ#R}+5K#^rzs+pH3`y1BkZ-N*-4Vmj1Etv4{Q|^@j zeu}oPm3VUJx5gS|=668j`3x}{xQa0iRPf@mG6rG0_gKwdFb>$pY|c5X*J=zWqBqPwqyE-KGm}d1`OSM_0Dxep#6QFJ@37DTE zUAa2sw>S^{lO89y2WICM_kLHY( zXDDRvJ%7(+8-WXT%dDmCqoC$SS_^bw^z{YnSUK#~5+n%uS z4lkYs+y-$^rA7s>?`1j{4<6mdoaM|2=D4*zU(arF3jc20KgR)l?7_IlzX`v^l~u0& zVr=HQay9ATkER(ASTa0TOFDd_gMr!~kv;4*ozV=iwYt+F^JQuEFA;Dgc$4bVH-|)cs+Kf1>cwFp_4g^G)2Go{JD+j+doxbcROYVmBgk)Y zr}fj!kn$eKvQ&8AZ}4`OoSCyFgCi)JEKHn0U-K#dUO<`f@9*3bW`JyAJ8$p4!D!w4 zxqX`Zg)}(&(p=j+8T5nhuB421|>`ZlG`nS>4EDRaLu!Mp@p2SpUI6_zlQI zQ25X}n^&BR^eUXI0=2vkJZ{vWo+g~3*{MVU81SXUy(;% z(n7}z{6c82V*OaGzNKd?G;kRMrv~nTSZ4J$a61_&(TF&SmdPJWEBfN42GP|fbI9%| zK_4{I$0H9!#IYF5l7)D17MJ~wt*^*g=vSn*-zk~~!?k}4gw?P!_>6-F(dxl`##E&9 zEaR&1XC8Fkb3NsR>)W$vbg}J&T(*!RXC=*o5?5+o`T?rL!3cflHLln2&RJThd9zr* zo~|23ZvyY95M8EK-PSU!Z{$G{Ns#n~hS{4-p87?)bsg}J1H5Ay@>s9oZmnGhN`fy( zk&`Wy)3&#+CB8)?;0dbwE))n5(hHT1NHd5RC}52DZ`a`HGxJegBKGb(Ud)&h)(ibf zgxRF~hhF~J`aj>sBkycQ9rLW~AQaEOzVdU5(JHL>!fJF<745jlprYvDQU*cNya!^R zwRMHYW}ps698|<>>j1qE65K0}0WnjnH&O9J3TzCdK;pun>d5i4OMDp-4b zwsf$v^g|kkEO3ihM&eYPUizB6wDLs+b4Yo@J^}lry?(ycw-Brq5fr@oEVvLal2vMt&L2DykKnRM5FTzCxN88cBLlR+>I|!W8M?1s6YP( z3h*+%1pelIXH1E!FfaA}=*{AY^z|Aw?_{b@Gt>aJ9F>kJ+qLP4<_X?c7{5CjgAYAC-*@@IsCb;>t5A0N`l1b!q;w z6ba68RQ@!UxU`~Il(gLo&r$sayqv*)2%LC4i5^(L8W9x0Tfv@J1EwFff>$gdx>qnTv?9O9(U+( zXAwP4I^F;C@{m6$_R4M{dye814jZa3dzwRs%sK; z+XBaH3{jpa5C@z!u4?3)b^-WWL=e4%GI|}y)As&&gWH|OKHLS&S zE+71&pJqaU2uyUQ<4{WIH3;dKdlDabadKxbG$^7k3RXu8nK!7SXV#a8Cu!h!2eM0J zyCD9Kj$zx1OWSAk8jtfmo{ka67I**UJ)oX~1Y8H=HkOJi;0vvwY1tQ$cC%8Qlz4i? z@2nAB=4^Q>;PvvH>^<({bY*pQVCbJe+^g1r4Tkk9>CY=|6SxZufqi|;KD;lDF2s_; z8@O$4X+HEwZmlEUW;){s2NcVbFi64bNPpk33+P@5siNOiT81gk(U(VRYN2llRyX96 z2+HV|_2nO3G;scb7Naofdp&`1Em;^}pp&|#2}8F)NH_Xjl>tBC=x44z)??-DaSvP( zCF=rg>bpt^exzzsh+H2}V9w%8Bh8z&I5Pmnez2nkK=G66J~#tlb9k>5UFoh2h7MU0 z63elQ!OY@aQpe|S;MTRN)d=p@WGP;lF7PUDF0R$Q^x))q4tI~ci#VBio8)gD_om zIfUfXUq}UVKTqF&4P(IizQ^6FEm&6xoxQ%i3!aBu>+~PhWIBH=byi{Aco6YaH6Yz; zV1apoYn2Y4sMb`(Mzg{9-`39~3tlrP$O9q@dZi_34z`?m3=pqfR&|XlknBJRIZqt2 zq{MwS_w=rGW}*M=dv)OxHG0XP9pdy-W4)wObDt)Cqm7`Mvwq=eXznlrC7v^0Mi`b^ zqBBFX_n`|A3B25J_nOT*b3UU_CuP(WVAOhqXA8;4xHTW8x4YWduRjT3HSh21_6hm9 z`+wYp)b9UqQI>jy2_YIg=+5^rTKD&T=&k>;#0U)!S8+(gjumV;1cY$MRy{hT=*g%S z_AUc;JjXVMpS$YAb$B0?Bv{wgtT88;klq(fu_E_=dRJ3nOY{(%o5~s3zJg2W*){ft zW{W=QlLkjd*xh=+a!UY92bTRpe>%u{4toWX;rrt(QI^bhV}XR-HK1_%tZGm7U=eB7 zQMwVuy_)o`X5NqKTwUs7?F8k(gx!tg9Wh9j)JzOVf4Vl1Kf;qQ@3srT4ysnv zBp^B(LmOP82ipKOY52W?u@*mL?iFdWoVHXvMnyO(?zaV76+~RzbhUwr`^%qE8X_t|7TDzA`v`Vud z3oY7rAXaOAgrV6ei4z?jHc8;!M;lNdC5}f*SpbIqo)VgeIty5IvrJtNW;@1x-sC%h7YdX+kmwA&vTxwM1v^ z93-FP>6y@NT}s#$lf!dK7Kn1xY8C?}m4ooE-%VKZ4}_ZU+bn68<>~Lf{C!e-{2L!j zXTvPw)}u!kAaajjX;SI%AnH}nvj4&uGS${KQxToL_AN0NcKIg7CV|(Ab|3M$7b*?@ z+@2M*slVjU*cowx@lKlfvw$L8VY(Lfz+@zd;Zvs%Pl6c-&-V8j1fu7#ArJ(r?%~!+ z5qI@2e8m$MTc?F2gTuxbgi>2vy1U-V$+!kyi=He zM^I8(urUFNueTM;vtTN5zT`3*I9{FL0t0GTz!V#TSN!41zrlyo+P9coljRRUgoQr< zQs9MAot+-WRd77DnC@eSOKPOgxzWLK>V&F;-H@)Wlc4Fzr3lNxg}HrWr`1iA?U?>^ z*my|AxVcCXI4t6hFQ-VUg+W}RZ|nfq{k-qjJ$G955ry6#UkFS@f|C8{YVZqcy*g*m zu(fadb1_R99lVS1c^b;e0>TE_9@L$kV1$0s=HuVT1%bdLQSKXHg?5Uix3tfpWwIlh zuW<&5fc;^*h3(fPueW|Mx#stg4?4SmqQ*zxZ^$*dzNFbvyoy`fXAB;@FdpUrso>-!L2W#9t z%Zs?~x!dWCaLs^WKk&IdN)Hdl6c zgBDWNXyBLCEx<)TWM%85o;E-0b|qVyWx>eipCxhyyyuBnL#_ztlDt!x1*=Ek;;q`r zg?|{Kwc7gPuW4LG<_mp0@=YiuE*NzvM_QCj{ly3k5;S@t{H_X!OWZf_Z0zJY^PuB@ zjKWw!>8=e+gA3zpZ-G4D8oyOR0dVAu%pP}no4C*_Q`pzPmguW{yiQ0Y&*OpXPx!Am zO;*$7fbWqA?np5<6o;x+0AL00*7eHs7l-DnI<$52()hzA`pOPf|VGtZ3^`*M_na(c=q9 zGn_U^ZWuU{WWkEI?k(K9p|1!$U=;XusjIB^D$7jh;yIsinutrS=E6;!MWZDOvI~|W z!uJfctTmtH!QRBDjE)1g3VQRGEQA}B{wQ^PU}13IamgE0Vh3c;^u%ljeZW^HBC4i! z1oe)TFXp$p#uU-J8~luox_@m8zC>hb?z#7%tbXI*65Sna^v`X3{-+|~f8x>~5YKg; z&2M>&5fWewSBTG~!(NzoR9hPJJ>my=O-r7Kc@uxaP3E={j6r48@5#X*)a3Xt`MZOi z4qi5pmBn5R@MK=rFegL-FQs}b2ugHi9pIAYZM^yg|B3@^&tTbo89c) zJoy*6Kxful!CUwm=(Hw!X0>%C_xUob1M=5&hR5g{Eru5ecuxOp#|{52iq69??mlwuI@n6tV+E$I#%FKd|=&} zGCF(pnLH2bzTXBT%@iuIA2iiQ*Z-Ws7m)9PX0;c-xeY9IWOu8f_)lxF9g+J&fo!o` zAirOURl+~06_73iWItCk0Wv3@6CR7^(d?_LSNX*Pj-1fqa=$MRX$usJ2N&A29e^tj z0dQDVn=o_xhDGfZ=Ou$FoKq@^V_i*0mootpCoc()Mb{7E@-z|R9%}FxmnEpAUeWJF z>$KWA5N*g@iDtggUhIj6QphUJnw$*dfd#1u^S0V4S+vvYSI6AK#hea^l9>AR0kxD; zBmQOxeR??5+E-`4~uhT2#s z5_1cezIH&=#j2M-mJRr7Mf?UIu+`26#W~1gj!KI^Hu*#mi4YuCIm?wVBI)X(N}IC- zdPBu;;J~OSR>dU~r)VN(aR;veCZ7p*NAAjCZCN^FnU~V|{CMDkjW@H@6AFdnU?Kuk z&&aav8#ocvMk6sVw{Ru51EM3Q-ey{rTH4-}ju8^17HMpo!e_ge==UsYB~!8Skx?5f zZh64X9ancKi4RB7GJ+F>mlnv`Fp-fTuWwmuDA7bL;!^FsBWb@fdDjVtpKc*C{XP6G zw%DVY70@}z+`R{mPfP*!%(88u$_o>m=(5_z)^zJUjAbzK;_G)@4_@{LN=he}`;Rrs zq+-;7TVsudha^<9CVE>L&;pW)9xCK}3{UxH+1MCfn)^97 zx6mhQaYxj6OK-Wq6)1vWECtK(8lw+M!OiLZ*OS-bZ?F-OCV}K<%xz2G!fe+DzkX@t z4P0i#NL}Yakpfa^V2H-h5ovK|WQlRj=;N$ly8jYXuCKwv-!z{Tv00=*%gO z++I5iZ=cR=^72OaWu}P6qOZ7gHr998`QIN41tcpy&wAz(B#n7YCIdzo{viT9xmF$p z-V;6E^jL^Aw;Zbz{rB@QIFmv<9L%aH|q_oXn5(zt(!KeGX1TSD^^s_o0{#1uH;X8bdSVfYOMcsCsRcIxVwl? zCKf;JTtBR#046Zw7@7y%os4n8_ACeMBCM4)xF+1fh(j|tbZn&jt4jwzyf~&|cbPX++Rn%5y^YLzhNh^yjHFjpFl%a9r19Cr zds{_cBkpH_mjm#s_wDd`UEZC|XFu}d-ajC0PqkM8-Vg$BT%2>ird_DR{+MRei@JxS zApQu}+hLKq=M$CQve;k4@3y$z6Daj6U$2}em;3q3FE6trk3Xzm{KZCnbn^6R(r2-S z)oTawm@DY=<;ZpGdC?kg8$<5N4>zg08RJlB->2Vtzvj@v_u{=v18M7D!>HkXOH2Mz zeQ(OK>_!)$hGBv$V%=-MWj}fczPGs9LTy)0M8ZO>*|QG#W{=ytU!oPd9;G_j&D?(2 z97_nf!*UQ&&*mo!G-f%H*FKZ=*->+W2jRU;{Og)Q!j00i%Ca{K63gy9#4F_*9yxvb z+3hH$v*)AEB)?jrRL>UJCeno%1|e z!ABY!&z&%>iFrTzE82BR5wiR8I&xh=mg0OnL;Bw5xHHT7AcVfk+jE3pQP)S`l&&Sl z=`Rh{m16P@|7yoz@u9QS%~ALF-VXj^Em<#%|J8O~{7S1(=#e{qE7kx|d-?TEpF}Xo z;Lgs4EY8btwn>q9tvYtroMRNNP_Eo$ip?q^V)u_S;a4+cN{SbJH-+hROeMx&MS_y0SbqvNTE? zYe-l&nmKmefT_aD&kyVF%&9tX{c2nv))f1t&>_GwdmP-P3_1Q%0jqp>(+yv-AxGPg z%L?-L;4ZviNGj$PFn$HHRy3xUeH_VYO~2lSzdn=44ji8{rZ}4kE32Or%{Rpk6k0Jt zn;J(j7a%8JDr`@425ef!kJ)#%rw5?EOK_gQQg~zrbHq{$Cr2hVlH-yLl5vG(=HKD3 zJ9CiFB#y@y))&G<2R*79Hs>Pu9Hz8**ZQ7;AP2mEUgQ|PQYeug*2jt#O=?W8pMfYw zDb!7e@Fr;$XWPO~#6RuPC#7@um@7IxlRsY`;n5F;dw%% zG2!Xy8)03AOZbJ?-y*ENDbDhTT}CTyS`y;Uo~Z4Pkh;>tkoTXU4q%YX?^g}dM;oSL zv?phh*0SG|uN*#lbJn~cIhbDUDKc`>z=T>}gX?UMKd`G`oGzg0m$hWET7eDQSxq~4Zfu!ys4vrTC4HfjH8P0 z+J~fbwMf-vwcelBl)o-tN_}~Ljj;hGw!cye8;j7<>Sf4>esip2TxNpw4dCmEl90qW z@OZU*9wyS@&T1Amk84M&He2!f0fld6hkrPmhYKEhBu;F9sT8JCohc9+)Usr;^*U31 zeIHX#-+<@&??0NfC#N#YCEk&bA5OW^E?q#FSMzR*(V(5^!kmNnM=fHd{kk7B$KqXH zNZdME1z54$)SJ>{T_RGa{owb99x_AX&GJPSp#}!;hTKZKx5xFdRJTFCtF$|v_FEru zix1c7sJt)y*BGY|zMgdu;`I5iPK37bb{6Z>$;@v( z4yPcIQ8((%MWjwaL@Hlra<4vU?^`J(fK+`xpGfNzIhl9+1L-q@wgS&=;C*42US`D{ zLX-sYhFMQePWEPpXND`uov+FB751znT?MGRe4u*nxIVW+!XecQ6EBNJWbf94hu z@w;9g(_`$qu1!f`Oy7~?oRD~L{cpYTah(S52F&8vt@d@3#+Yfh@r=HC;g@GwnF4uR z>$-huO*`+x@0~tBpXcdC(2q+(u8-ddR-+gB4)}(@EdFo?tM(bZ;bV};7N3r&GAXU4 zt>|`rnuR|&+fP1lX!yOi8!l+KiYD-?_;_@A*`kCca$&so;VVoVu%*hKZb z?YF_6fs{tQs_-wG{t>w1El=q6KNQS1UOmHCLu0%;76-%BhUc6J203~E$c`tc`r zMlT{w;*fK{*}3dXoM(xFjX`6hMf@lOlD+Yuzedbae|hDKc-E6@jK98tRo$`?y+>m> z?nHgDF(E0uUk#fUM=>z*`XUMrYx|~58GRDlFc7ilWsA%&??L26TN_kW1B^BhN_+ZR z!NhRXG=N%+Cp)Mw-r^KKe|g(?<00o$LTS**AIER?lt(IwQYj-9 z+6Xaij4Typ4V7(*LRqFFvdt*jlXhE-Axp$0Th`HHDaK&z+w@q*jJ3?5xtZ}j_w@e0 zU!VWr^ZLwh_qnfgopY{p?bo@_th^1npk!>R6jx)3pJskwjdbcd8TjQaSF%;#yz%L& z)!?UM@k*$U$YFb*ScC3pIDl#`>T`5Ou!bKV9@!3(@p8W+axXD@A|6+p>eNWpRi7j- zHA}GkJ}xIwua#|ks=JgR82)~x(r=2{t>SN}Q!80l$m)wMket7ll;_*iwM>5n$F7&W z(Uqys9XY3R^25qIe0Lvh%vsxFXL9MU?YP1v$GOR)5&7!!pVP^C=2(N{?wpGG<@ZKq zKSWQYAKT&})mB2P(eduBJjj*ZrtqVnD6TthU-_ZFpBJh~Q z>sWmad33UcD|69w(r@_qoJgGVM#Juha6t1tiv3&0r%e`KI|j~TvPM6~qTh{ut*1VZ z;~U(`p`{g#c3*$8WacKmI@*9c_-Z2NK(?XZF^b2G^W5jSa~3``GEEKw!a#<`yzEwm zAD;Zm$%fbV-P0dV>nuI+8}$}>mhR*b`luA0*7yboiys`HN1dt{3c``S2MpTEqjdNPkPcSMRMLAU}~OoyRTw*_? z?YsVvt@^2|x`PCSxFr=@Y0%^cwRvt10(Q z&YZZ-M?Z6A9ET>_77d6?zh*~6l`Iqu$GvY2nGpMy*p5kx}bcIkYc4dyfE z${#7eFuu0I$wOfAMKM9Js@cx28^_9yBOXSbi)!D0!ZpMDQZRp1Lu zy+1}7d|>CA#)r}(l5rBk$F9Fs5?eR?@vFbVt#2zT_9XzR!{r7O=Q18 z55`x|neo!jXFB+7JTva(W135j(fbDQ9LNQDBKtD=HTa=dem}-h>2);1e@dy^on<#a zyjZSKHh0*dTi&9{Ut{}pN15Bmo=+GkD!QebwbKeK8g{GwHh*nsY3qBNK%cp`i@11+Mynl$VH4>T{(Egk5a7<}h z$+S-h)@M+A?sH;v5o;j2MQz^Sku^iHrI6&)uitCB&+oBjRV-?^Wi#f}g9_4zJv!d< zhJwnp$Hx61EXfxqikv$?(i)LP2@&rb8eHOiOO|^f(Pg#MaNN?z^c`(dugq{4Cw?mn zz1iSpvs{%8=E;_d4O%_56576xXtuxIc>{)ZZRPZt%YF>8`SQao|J6?m59=Q^A?%i^ z;s;9nI*22f>fFDm9@CP-+G$B_h_*#*t&D`i8~%~pSLw=3?9M4b(bo+smfTvB3~l&B zjjL87HYq2@R{LHts+s&nIgEy`^dBj%<;oPlT@9y9yZa8l2(~?88v({cX zy5g0OAJH|aYa?$>F1wk9>X+^utf)cx|5$_PYvX>5YZ;#zcf1p^;zZFO8!z}Uxk1;I zdW0W#IL~2xHGk@R87~@L6EE>gnw;*fZ~~p~Z4jJ#0P%^70M1L?C+Vy@!})F5xwa)6 zs{6qg#O=r9evF@t#)_vdx0=ZXXQFTR+TaVKW!<5Eqgod%b)pR#?KD5QWV>O0jcR@i(=K3kg!U_M=DwqjnEADsR1T{=u0>?t zKc~QD1LwHR1X|R<`C!k=F;xL;k<3(tt&Y7@^|Th^wf*+!%uu>oei3~$h&^Je1CvS#`w_yug>vHZ%%k%Ig2xN+&_^yM+1XwdeKjE8onIsEVM&m z2(S~c%BXy@eu*)c5%GlMDXaCGh*fj<%Bc`}nzO5-le_x#``og@Cqt8;Bz3%)!8OaB zxG|}JGcR%97}6ZLJI~NE;h<k$EG5am7Un;z0;{QcY4(?dqBOWpl;P6sG0y%> z#urW0Qtu0y``!9+ixZk)6f?Cch1HwHi|rWK;&03r6{5(J;}_@Tu#Qp)6*2loK>u)iB06WIgcEny{du zG*mTH#0TV4!QhwH4&YcAwxqyhj%&3~8si_69UD zzqb4;=E)>XPzs)8W?<#0LDOJdUCqC|eSC+O*MHSoYm!;bm=R@hex*_A!`otooq0g(w3t=? zw4Lpnyw9ky(BN?rzm*QQ2YucL*PW8IP>jV`W1c9MuxdoK=%0JuqZ?zNrU~iitgVUeoTy_sV7d2x_ z>joEvfhd+4PYrGsee#C2t77MHa#ydOAZTB8YGC5Z-Dh|aGlQ2VO<9R(&m7dn7ehAv zTED6*=6|1dHJ#gERUF*Db{Wo|K#e5B@k(SCz2IdGv*gpKXtRa z(z|#sSM+82t!!rH(&w`h4vVj=lTm?YI$~RMSy{)&O)9+yV;=)=vU=HHx%7S$Msmx= zpuO^ohC~P4U}@1JaCB5_1b7OkoHptns&@})$AZeZRuR7G0#FpsF*1fdYu2XatQQaV zf}_k$y}laA7nI^%M|1isO@{eR8{6-{LO;x3s}JW^2mg%XxuEPkBj7bmCBy`0`4 ztzF7e%Z>9cthWdaRPC(K=E;RZSA#gb;D_{y&}d4egl&aYCCuGehLF)I6WCmTDg4X2DE z4)(mC+eD|<=-S|PW>~2fWaydE`YH=`JLh4pbzbQVdD^a<@!8LuySaAgcLn;82DSpzn_KtkqNdl zOF3LR=ec95c*Zak@h5y!B^loOigbA z#JtV~U%h_X@gBNa4X*T8CX=lg4T_9hMiL&k)!3V*u3agfXax9uCjYfUR-VdBt~!LC|};t>Zl>k zJ9cO$*YP@lD^X2V$E+Ce@0(aXs@}EZDr6p2ttXLyuT?M(YU{VlC@asE={7Jha_fv` ziu!cK4H_7>zi;(j3++E~ko$}+s+#_-v(&J+-?lU6rb7B&-?2pI{KQ1V-SkHbcUiYr zhpay;2HXJMGcO}c2bzQ0Z*y>|ZK`QekhPF z`aJWWtcTTz$}WdDPJ2R6mGVq5t&(-=TVtEY?Q^iwQXpYLEI5kti}ue?f{%xs8%S!E zTnqVY^>A0qJu6PqY;H)sE?89J##~cKx11_5WQK0+q=_0l#LMis2ARuu>f@5|zxF)$ zvBhvMZJm&z7#Li~GkiEh4qWfm79!C#iIdM;wbnvwd{fz?r_ ^<2i$L4M%=Un1_pI~{7cEGPJIkx(<^#5X;N<*peTr8i<+cA?)MkvoR3JLRO(TV?Ndl! zF7vJ7vCk%Tzsn?s=8P^;T0fcZSsn7v6)#xirE>nl5Oq16L#5beU>|RmwD@mnP@5@b zs)1|Q#VA>PpZ9Qc%XuxLyJ}vOuWS6$GGf{tzi7q(@**;FxJ||^k#>q!HBtZ{kB+Vh z)IYlol77&cg|dqJk?(t$^EtSgn3REa16YG9-9Pe3ORVw32XfQNb1^fCC1ep@$?YDn z$ZM9;Juhb+{vpJTQ9Te9seIfJ{iyn<0f%{VVqD$W!z`j@-LxBI{wOzM=qUf{`F%rL zc1aSGIKj6={8i5*BcBiYxl?DW29_J;n6e&e#1Z9%;OjTABi&Re?VmTU@Pl~c;?*aT z822CWuqe9fwy4OQKQMJOrzt#Xw#^b^yuE=5)oaocPO}(8+zo`xi&kEvl2%L zGcNouPa`9Zv$xQxW~>`E^IPHar`M}@C2j3%g3=zDX!1iY7}|5=<2h>+F)emrzt0VT z#Fvbj7N&&kpE1q#-n->3A#Ck7=xR!rjnB&3?^+y!o>sSQE%*gzz)nvNL zIS*A7;%DAgY0@DGbEldu>S}x+2mod70tc(ot~wDJ8QDJly_e~1ras$hjLEiai54_= zwgBL^LtH<)MEh7*ekiZNWS%0*FZMl5Ju7$7w`^>2wp(=obiLa->6d`T)Gzm}ruy~R zV8$)$9d1A&cVjj9@(x~}Ny#gGF;3Zx7UjPnj&nc~IwyOj+Blz8^gJ7wm}yH6V=x2z zMp9C8OKu5=szmg{-&W%Em2kb)Gp&3wCeN&elrN>UCTF4EH+lYfh9N#?e4;P+c{eZl zYT`b{3j7Y0raSkM-FvaR=`z@k7*z#@^iRbBroGi(6{ToK`V)Lh*4@fl2zqs*jvIO} zY*43g?)x8HT>RioL9PXJwS*d@I#J+fYTQ;B{p5?Y!1WG{lHptAm5M;Q+yu7h^j-J9BNsj_W}8@)eStNb0=#Kzz2%$;PVbpZJf2ZHV!^r{Uu=P9Z?#rFEYAB z$*YyTXz6yhFV7y*Eq|iPPjkFEV%BN)M2Nx0M`~ClkkuVvEggLQUS;v6Pf*CZL3j9b zb-P^3JK|m;j(3Gh?C$&fkDi!*br?#sTuR2@CKo@cd>y>+NkIBuu$}|qa;YRNBeV4& zX$M=yLjignPFy#+P` zsykBoI|yzmS?5U&?GDYWpmvSV+|c065-%q~{8_G)5)gHZ&6Tsa_yH<)0omnG) zhPGbJLj5{8-GPU{3sKw*7QFSZd<~b_uX9MAQP>JSO`OR>ar35Li@`=OkwJ`NPuNhx z&y&!4cA4e)HPH2I&)K3Y#(8!P%e~3-Qu~F&Bx&1F@aGHn&>cRlf<6}AVI8NNL9ez} zhfS+WOe$F+J9uo7b%8S>%kK8t@1tK4V*}}W?eu_+(tf~x-DbH6ZSPE%HBs%3wv&4; zS<|h)Hw!L_K*xQ;*h--XPU4>8@9qO=qU{)zt9WxIzU|?totBgBjP64$?ZvG|Q<)(k{AP z>MCfCy@PJH(Yh<>EN8_oi+CH^#+Qey^(ZRmGoiYFsOqjt$Lhdv`NmPXt<1=E*{55sz3-%)Eo662Me)Hi1Zu zvS6HXvi(ZPD#!bUuN4`k`4QijtFGyZG!QC3qFgY zVjMDw3CM!x+9t}G_inMf?Qi-7*yfo+Ap;vpj70n@qjw^rlS-}#?d%sDM4S7M(#a+5 zZZ}Ven?kxlZ?3{dd&g9C3^7JhfOcaaYaHg?-yemKb|}V{C_?fsUPt)XpWo#)Oe)gxeh*rZ|hq&lbBGti_FR@x@HE)>4P<`l75#HAZ5#_ z3Y0EF9*TWFu@ymdU~;U#xopsq;%ls-vnT->s#q+pj_f0+;4PH^hTI(1kYOx1PLSCC zn8shN8-)y!zLAwf96)+^%~mfpBi#Gye_k62U$fs6N0HZf7A`J%cIX1-%nx}4`98%v z0Qp1_5&scE4#PJ&+J0^1SoKIDZsP%f8<7kcVUND)ejAG7|8!JAI-Xe2<$nXV!XWbs z?Fn3Bz7|r*uYkQ{6 zbtkSL@m_&Ki04MZXey_!P~_zSrG~wJ?uIqZ!V#3Z<(vI6Avp)nOvtQ7X7VPb{Su|? z`w?UbIaUg@qMJ0w_4unEfE7lA1E%cmV^_Y73q+t-eaE;tY^C>)Z2?wuAyzjo#P3s# zDL8lIKT$~cMJw3^bLU3K9*ueNwP3QwzA`EAvGnV0hxfl8|?_^m5Xk zZsxKbeJ26G`!tyQ_nhE^{JwoLf-QY}!b)}lPo<)Z`@*(9_LMCp4H@8m8QmAwJpX$B z!ZmQilCJTL7XRDpJ7-a8*vp9dUxqpQ%zJ1$+4`f0?mGA55Y+y$iz{VcKh1EYG$IK8 z6#Lfrm)wFijbEpveA%%P3MuxKhHJS}4)usu{%*{F7zzkgJg9kvqVoOprAy@jt08%D zstKm|MrW5@0;T8z>i~iqjPqrQvwc>S(ngE2 zONAR(Luo%dUO1ZqX6G^Fx>fA~7Ud$Fp{q5{!TcnJv-!DB{54R>w=-G9z225w-_K<; zU8+|Rpz7CV8jPw^{NZOAJhr~E9oQq!AaZ+*^|OKcf+u+*2fbXq$Zb$44b;8leV zE&kiYqO8ZQs&1fr&T!5BAImRmU`_pv&KwEo+{=nA;wkU0H2rc_2yEz1yOWG6`V3s6 z_xJVNfGnbcw@ri%GjE(Fa{?h`7gZ)1XK|Ktrtz8w;OeN-6t)umjdflYFII*na|(cD z4zV7<_f9`S22fsiG68Q%y}2h&ZDo-I*GV8wc(}+4DX0 z<@u9b@!f!JEce6Fl=}Y3Zs<5D20>}cni~AQ$@EgPD}H#etPdce)8u1D=T1Aibj0wJ|=dukT(k@wJAQXZ{K^$nor z^PVzV5)tSR9oj`?8vF8Ju$4xtd~RVmgj1Q=b6_g_GB4rK3`!_|<6n?}7l4_16Mv#i zjUd>{e~9?{GlM#9LH+q$Z@*M0K(X35>9Mla2A%oNI)p0xHA4df>29EhFxc_JlRq4I z5M(}lD?$g&H%N(ZIn}lN;uUPT6)f34fTzXLSz?c~PHE*=t&srwf(U$oYvY+()aG~x z681Kj&AVjZEdLZ+xcqor>>9eVnF4afZ-N9*PWh%vW9tK5Tmy^MP-WmwbSbS zXMWx7(gGJ%Y>o#uk!Dw^rHNHHq-@#)RH>Cz1X7|QhH`rRY!);D*UPU~O2Vtt+}r$i z5teiC7H0qv$*EOsRd&De)eMQ?O?`NN*m?*$N4u6q?BLi=Dl+{{x>Q>MDev}zV7DP9 zo#-mw8iTQ`1~*_lzNf_>Opg8=Z~2JKe}BQ7OJzGI+^1e+G*KqZWV|?AyvJK+z)J}gA~GW&qP zy~~z8-n!~uA_CN}3`$8-gdz8u4BnR}uJ{SSB|qRLDGM&6QWb99XCm+jwRa!ayo_J8aLy05+|1Gq)J`t~G{xnJJDE4*~o^%%M;QV+*bHpwZ z5hdP3)?eBNK~Hyh!G@SL#jYLVp zKQMo~1Bb(ddfh4{XwUPz^s;(WeyXVWz!!5*FsZ_Jo#H;Oc-X^EN+pkuX3IPRVmc5E z;zH|;W?8Qc;?lZ-V+fq}!K3|L@$iRQ!^#|nO1J7JBxO*+xeKDfiSde6i`Q7n04(ar z4{l7vLmP4d@9lp~Y<`>SR*<~l z6wc!*C9I5H<0~L38+xuRRighA#!M{mNJlfcOU2?qIeFdkos*t8JoPxd26+BA16|+o zJ_ulcqk&E^{b)xcy!Fqx{y;RR5|Ba{km7?OLt5ib0?#ISa$MmWBRqTuP~`jfEm}XA z^!p=Vno-+S&jCuTP*KChS|Xet_}n z&SIh+%@=}OC+ZFYW@Q8}CYl|i1_5vF_`bEln|E9X*RYI5)*Sd1Ojo@;I^F(l8Ke}5 z?>kgoz)B|Y)jdJn+UJzdj5s@~2{!=yDzZl6k11W%-pPX7`5=Cy+R9H6{_tzyg$>1s z|EOsvyKLaUk<3V^E#VN<`*&=I2e>f_m#qLBB%EgA2J?}m;4|KfBC6=FTq4S;M*;9k zqi#g2eipX*Tb8XR_3X|Yf;msPPF2!k{{qPVob{p8MAbZV!K$v`e8ZN}ES&r{Bs3&n zfstq({>~Jg&POdd53E8kJ)0r9now$^9L_Er0iij6I3Y3zn6N_s_)@q~hdFo+%<6cl z5zCma>f_YAJB2!%nu|RoCAqJf+?7B()?MXrp5K!iVyX#L$Eg#ixCiN~0ZzU6>1G@V z0(1dfK1JJ0XKX!ZYb@8c^w1h5(g|Iunf;Jox$?sU~Ro9UlZehh71>OH{MONmsDr-F>8qXYj~@(028 z2^;_vYg6&bX3JPa-C7D@0{cw3^#tE$3QAFA#x=YFn*S-O*709YAa#(Kk3CD1u9~y? zQuhK=qeXM&dM181C|a3z$7(TddGn7Y)iSpOq5IOg(c#t&+)XRhg3aBplM{)3wB`KD z`IrEpNCT#QIe3Tp5tmgs10Rsrzilrhq|iOu;u_-Lsr{|J@;xPOYL62@TN#7uK#ct77IB+@uz zrRu5<@Z|o)w>pa5Lj&&F?5oGRl!Z;$SL%?QL_?7o+csI;SsV!B@K3TDsvh~C&q)F- zT{{u37$I;m*zPA<3?C`}vH02=i4;#T?w`bJ{U#I2)$=}xiJb|C zH>{T2M_K%G`R?**_|9Qc_0|c5wR1X*NQ?yh@7Fy$Iy8v**LaSu!FSK^(i|5sXwjom z`QlhGsQf;=Fcq<24>-);X>y=GsP`!U%)`j%bYMJbyK+#J&3)aZBA|1j?Y;YtYI4Ka zGQLrswV#>fp#sL`O%_#wE~z~HG}qZi&+g_8)D5r=y02{?6^I49!-kFuNMa~vZ8D+4 znDSjd{m;F5a7p5$fcM63@ex`_0MgNp8ItS;O3!(ZeA#50Y&OGVlf^0cYc&%%_h zeUqfG$k_fRu5LAK8A8Oa&OA~XW4O4|16<|zMpqeO^?;oqCw64( zNEY^}V!?!LVw|jppmPV`B@FoQpw|3*A1Pl9l*1t?vU=pb$L}mhUBv>Bah5Ub!r4YD zR}MMe!n?Wh6P~wbg@LLMFo63iuF+$%uon~yqyiFGT%zz&`UY%2+AC(PEUV$!KMS%4 z1C@YSK%1u?wF0fBB83DrSWRO};_md0%4HvZ&$Cu$#0~^kbp5sZvbAp=$~H3NS~_qZ zz)=^#3A|cx*v@d(lAT*5*!wiMdt!svZ}{D}QPq*6CpIJy{(Qh^fa8>&AP=}PpX+R} z3KZGv0XFl^z9k=%wGlRPQ|JR#ljM3f`V?^8rwW-RwAlz$6T-qrM&UnaV zMzMbJsn}1}6yELwoi&8d%gxU7&Zk$|$qJcM*}p{ZtKMu9{@IQttpYC{ffZ5^!-Yp0 zzeCTe&z8sI*PpxE{YVSwUg)ZJTfcrrvi>`n_l0DAcTQ#Y1lka&`{(g8N(Jv58l-_S4 zl_Gp}oqd0#f0gB}{=-yoB7>nTxvvBydx8H-c`em(iPVO`jGDh_RiLZ-O0`K2HWSLv zQ4$r5Ei?W^Q+xuIi?ad6Apg5(Sl)EiAZP602_^`$aJiAgLqxfwv;Ects$vcyOa+mX zH0Z=5IiS*xNzP9=A$r?nlMf#$2Jd9P6_RaCIQ#c- zlMkmKD{*t`J$a*}+x1~Z4*-Hl)%uHx_-k(>1ALESyqNqYa4-xL+x~+E;_{%a*SgtBj&jda8gUaqo4=)(Bq>03}b_xISNt|K)^a ztlU*W-3xewtVKbEM~Dsi23!3%e~!K-pLF^xlI|t8+KY`&G(%pY^bZkMt~v|02r+g2d8CLom!Y5Xj&fY z=O!Odw_3Ut%afzdcbhg>p0J_;sF2NteynSB)o)ZB)$;^G8K ztEZ8bz0Be0VFAtMmQ301g6;-x@~QMWTmMkOj;K4>2$gl7R{@Z2)RG|!PgiYs#&WwR zA`0lZg-HCs!}HwkGmq`$CJ+z^KRneso`wC;P{YdW>`2y0&uKF2#!9G7^IOdk&NU~M z+APRu%nxfX>?$RLZ`mf%AyyTJ3@cL2MyI|3b7utT>GRzrKNHH+xO@HG8kFhH{4-CD z$!)8-J|=^AWu+QYrKaaoWzFMH0|E6*jFfloy2 z(|FM_uQ_nZBlNBIGpRF+A^)uuh=;6^vCE}cb@CN`!bb5CMdTk_b=Ny=gMV;k!!K+7 zyvm{IWHHPw)nT7ZM01YkANe07_7Sb>be!B?8Rddg zTeTRUzM}xXr`z=PW|Q%Ic6&C90Z%o75mdo9Lg44>kHdU5tl0RvjGD5P~SptwYR2jqjr0cSkgFMc~MHc`zjN~#5Kq`3w;dBRN)%g`r+O;DJ8z8j`074lSXW5Zj3 zUjtkq*Rs}>EXK>m36KaG+ycicgSWbikNOZ93wiEq$?~M*%=c>IuGctK;Ps8e^1kVC zRxI2=Ee-fP1W&0XFPIwr9#o}dFa96^?Lu^4<6)8W3VE%2ydpwQlV5Mx-lk2(+}EWT zWiBJ%OdYpL8``h|q!2*Z|2dH)VM2Mf|2}XZF!%HEMaJd8!{L`(r+KZ@1bH<8qEBzN zr{moAnrtUAiY>hYu7?YP4(L)g?m`SR^fau7RFcK`DP1)pp}z9#8h`C;^;uAI8MhEg zx^`pnHv$v#-c!1w@kh;B`|95PZk5ya3o_T|&%AD*jXg=t!@b2s%=Mfn=^)gG{9Cn( zo4K;Yhv*S|e)wxkVY+(eEe1E&^RhMTFNp6M7CDRY&z9n%Cv=?0y9u2uH-`YdgT7xh z3kyJ04SVo>zWHbEW~z^G9*^rLiXWeuX`R7TenHU4pV<-N1qRE#ihOz^qA~_D zi;j6&f>Vta1hEaOAl66F^qf%ShO^ODYi`aCa%KOsobp>tDC;v?Ssu?ZB)uMUxPYMA zT}qePiv4(+-TNtL#1=s2Rx0a*Jzf(`0P9bSBle8v_k?>nVcNP3cjiW{7(pbH3vTsEU{FSt7d${pdd8Q^ZF5R{d-K^R*+1@T8rEBb~NRX+~a#WqOk1T2hL`pgN{$5fGVB&bZ_7^Jif1v`A91t z?pTB1d7D?TrT6TriOx>kr;(0M*Gb|FY1vml#E`39p~jXgq*)V+ShLX}fyB7qK+^Q4 zg6a_lWzEetCwG`$M1XWvb|SHu?3Xu3LD6BYJ@8fGaZYMTk`+R@`R$asiKxE`|V9}5ZFOSmZO84WA3M#KkPgbt>U^eJUd7Zk0SJ57Y7@aRiYkj>eqn+93>TzCK`5*CnVa1BeuCjZF`~I< zFLa_t)(x8qxBuypuNNqZ&AI>a=Vj-EimyitdTciN!NTo-bV8XM#YVs0j{ff`KU_OL z`1f1HwP+}LgCK>(Ky~sk9d|@yrY#YU4J_E9agK1RNep>qZeWv)&q%b`<)^uFD;Cd5 z^#q5eQB8Ld3529c?{~AOuY=IWT)0O{w$wJt3b2~6GZN(=+Qc0iaB^AMr>yHx- z_A;#?i}5rIsd*&BR)MaGNTMq)5qwdB4EVeobfXvF`V`CSKR=(mWVK@mOQ-^$Ngzmn zQox|0Nj7J9r7;FBb-pN?Z}^U+#KEtN4*GQ#S1j!0D^fnfzMZHH^QH@?!X4MWGkFW% z;Qqt2^c^oooGZ(pvps4-2+|8xKOtNTw2zd>Mi=b&1I23>0$;$X;-ywL#!;J_Q}GCH z-TmxaYCQwleK+*ylLaWhF=d{b|K6f(P^bcgjeb(R&12@`bfP~TOXwh?4lKQ1^8*5W(q!P{olytt%e7Xo$)w%&Tmet|e3kg{jd;kB~MRuwm@d^s!N z6ia>o`MA@R$3!Go06`BM4uQA1eVOlgu6f1_MJs#M2?0VCq6|v;ep^FL@YcXRcHyj0 zHJJIbO>&E4iI@^$*JUg3n9pk|xgbyy3_turfo}7+^*W~#>%5VFq6g)}0NeFiJnMU0 zkuZWtn#1|;&cS=E&@tme1sJj}#YL@W^it=p7wgJ+M6~I`vAC9Df1!M(8NWERHhK9+ zv_N5nN)PiFN%NNd?))acQ$r{py3t-`+dQ}jC);=P7|W_j%KjdxM@iQ?qrz!F%?&4& zfi>}?bBo^bCjCYi*M!Uj8q4*!zE3?aoOgQ%!|6jC`Tc{4Q5=U7lr*Y#xM^a$aFgZr z=}6ZfwgHBCM~Ky#`7>^;$-MG?>S19|b*nwa^+?~GYCnw?nt1u(GUayOXyF@Tr-o4b z=)MM}OINj?sY@Ll8h4jg)t0Xo7i_a}S(N@eH`(zk>$Tu5CHyWXAwU_OyrSBjFk9^K z8Ku8?h=}-Q5Oi0u;&e(-5!OP=w23MXfh)t8{fJ3pNU{yk)U;$B|GU$NURAPvwfN7c zEo=DI*bSZE=lq5E<;P6{t1KKm(C;Vmub05j$%ZE6PsraVqwZ=E*0HxnJgpYJ5~wig zD#RCZs_y_dsqX4mtYc!0xbAHZrKVR$5*Y~^?Z2}%l#2Ji0jq?pVl3lsb|H}k_^sLO z=`QFyE`h)Pvdl|UVITf4m5@CZb#qJt=cCS?u$OettF56M2>yn% zt0D#S?~WH%@EBzz?T^~5zpwjzNesL7TFa9%)#CDSw^ZOI{wiJ0F7bsxhgb8GLc^mw z>J#%hobqv~qH>tJGE%f|Auvd~Z-1q}kk3PGxG4*Bv3Nt1lSRWaQ2iV84~&uY_i;jZ z3v!A8G6D#X>yO4lZvE-#2T)s5cc{iI#fm(0GJzSnrJASO-FJ5D6 z>p|hNwbeO<zpgB<0)Nl7hL@<}efyM}W>LQ`k^#-`ka%XwY99sW!*^ZzpBEY7*X= zXiV7H*+^Ftc1mN#YVw&nueOd&3ZEhKb+(CkZ=$jO+`YdI%3DAJ_cJ-yVQzsXT(q)e z=mpU5zHDx>^>4$jc|C9&QwG+ej5$jZ>P&On*GWjjSI(bLe_{3m{{ra91^=J{A>NlS zQ%oprs$@UTAMk%U;HPX9myG{P!TXKPOa8_25PZ)PPT;q+OzshCth9d&i6xhCfP=jq zQGchuZ(<)E2NPIdThH)#&~pl7BWy74TS)|Ws&;BK zB&3ms5KFBlE)Ych5)NPY?_6#~Bn#GrM9c}4|32Tjr-w>jSQFy?|F?utwWh@(&$*RN zLIB-Bx~HIf>(Af9r;rs(pook0P8}1DXMX0lN=W>=xklkrt(m>&^1M*5hdlq4yTyfr z$v2k}@+Guv@7}b+B$#}b6RIyLr}b(RgSj%fN@wF=OkoADm#8bM;ymFaq49d>`5B`3xl!%J%MJE1GK=C@8CKSW}2iNg`Wy-Y%3V%)w6_4DJM}{{t MG&LyDyZZ3|1Le=gy#N3J diff --git a/wise-api/src/main/resources/public/index.html b/wise-api/src/main/resources/public/index.html deleted file mode 100644 index 02dcf806..00000000 --- a/wise-api/src/main/resources/public/index.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java index 078e2928..6e01a87a 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java @@ -22,6 +22,7 @@ import org.springframework.web.util.DefaultUriBuilderFactory; import java.io.IOException; import java.net.URI; +import java.net.URISyntaxException; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -35,7 +36,7 @@ public class RestMindmapControllerTest { private RestUser user; - @Autowired + @Autowired private TestRestTemplate restTemplate; @BeforeEach @@ -52,7 +53,7 @@ public class RestMindmapControllerTest { } @Test - public void listMaps() { + public void listMaps() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -81,7 +82,7 @@ public class RestMindmapControllerTest { } @Test - public void deleteMap() { + public void deleteMap() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -103,7 +104,7 @@ public class RestMindmapControllerTest { } @Test - public void changeMapTitle() { + public void changeMapTitle() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -117,7 +118,7 @@ public class RestMindmapControllerTest { } @Test - public void validateMapsCreation() { // Configure media types ... + public void validateMapsCreation() throws URISyntaxException { // Configure media types ... final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); requestHeaders.set(HttpHeaders.ACCEPT_LANGUAGE, "en"); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -135,7 +136,7 @@ public class RestMindmapControllerTest { @Test - public void changeMapDescription() { + public void changeMapDescription() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -155,7 +156,7 @@ public class RestMindmapControllerTest { @Test - public void updateMapXml() throws IOException { // Configure media types ... + public void updateMapXml() throws IOException, URISyntaxException { // Configure media types ... final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -183,7 +184,7 @@ public class RestMindmapControllerTest { @Test - public void cloneMap() throws IOException { + public void cloneMap() throws IOException, URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -211,7 +212,7 @@ public class RestMindmapControllerTest { @Test - public void updateStarred() { // Configure media types ... + public void updateStarred() throws URISyntaxException { // Configure media types ... final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -238,7 +239,7 @@ public class RestMindmapControllerTest { @Test - public void verifyMapOwnership() { + public void verifyMapOwnership() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate firstUser = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -266,7 +267,7 @@ public class RestMindmapControllerTest { } @Test - public void updateMap() throws IOException, WiseMappingException { + public void updateMap() throws IOException, WiseMappingException, URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -303,7 +304,7 @@ public class RestMindmapControllerTest { @Test - public void addCollabs() { + public void addCollabs() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -324,7 +325,7 @@ public class RestMindmapControllerTest { } @Test - public void updateCollabType() { + public void updateCollabType() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -361,7 +362,7 @@ public class RestMindmapControllerTest { @Test - public void deleteCollabs() { + public void deleteCollabs() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -400,7 +401,7 @@ public class RestMindmapControllerTest { @Test - public void deleteCollabsWithInvalidEmail() { + public void deleteCollabsWithInvalidEmail() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -418,7 +419,7 @@ public class RestMindmapControllerTest { } @Test - public void deleteCollabsWithoutOwnerPermission() { + public void deleteCollabsWithoutOwnerPermission() throws URISyntaxException { final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); final URI resourceUri = addNewMap(restTemplate, "deleteWithoutOwnerPermission"); @@ -439,7 +440,7 @@ public class RestMindmapControllerTest { } @Test - public void deleteOwnerCollab() { + public void deleteOwnerCollab() throws URISyntaxException { final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); // Create a sample map ... @@ -458,7 +459,7 @@ public class RestMindmapControllerTest { } @Test - public void addCollabsInvalidOwner() { + public void addCollabsInvalidOwner() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -479,7 +480,7 @@ public class RestMindmapControllerTest { } @Test - public void removeLabelFromMindmap() { // Configure media types ... + public void removeLabelFromMindmap() throws URISyntaxException { // Configure media types ... final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -524,7 +525,7 @@ public class RestMindmapControllerTest { } @Test - public void addLabelToMindmap() { // Configure media types ... + public void addLabelToMindmap() throws URISyntaxException { // Configure media types ... final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -548,7 +549,23 @@ public class RestMindmapControllerTest { } @Test - public void updateCollabs() { + public void fetchMapMetadata() throws URISyntaxException { + final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); + final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); + + // Create a sample map ... + final String mapTitle = "Maps 1 !"; + final URI mindmapUri = addNewMap(restTemplate, mapTitle); + final String mapId = mindmapUri.getPath().replace("/api/restful/maps/", ""); + + final ResponseEntity exchange = restTemplate.exchange(mindmapUri + "/metadata", HttpMethod.GET, null, RestMindmapMetadata.class); + assertTrue(exchange.getStatusCode().is2xxSuccessful()); + assertEquals(mapTitle, exchange.getBody().getTitle()); + + } + + @Test + public void updateCollabs() throws URISyntaxException { // Create a sample map ... final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); @@ -592,7 +609,7 @@ public class RestMindmapControllerTest { @Test - public void updateProperties() throws IOException, WiseMappingException { + public void updateProperties() throws IOException, WiseMappingException, URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -623,7 +640,7 @@ public class RestMindmapControllerTest { @Test - public void batchDelete() { + public void batchDelete() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -646,7 +663,7 @@ public class RestMindmapControllerTest { @Test - public void updatePublishState() { + public void updatePublishState() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -663,7 +680,7 @@ public class RestMindmapControllerTest { } @Test - public void fetchMapHistory() { + public void fetchMapHistory() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -681,7 +698,7 @@ public class RestMindmapControllerTest { @Test - public void updateRevertMindmap() throws IOException { + public void updateRevertMindmap() throws IOException, URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -709,7 +726,7 @@ public class RestMindmapControllerTest { @Test - public void addCollabWhitoutOwnerPermission() { + public void addCollabWhitoutOwnerPermission() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -736,7 +753,7 @@ public class RestMindmapControllerTest { } @Test - public void addCollabWhitOwnerRole() { + public void addCollabWhitOwnerRole() throws URISyntaxException { final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON); final TestRestTemplate restTemplate = this.restTemplate.withBasicAuth(user.getEmail(), user.getPassword()); @@ -800,14 +817,19 @@ public class RestMindmapControllerTest { } // - private URI addNewMap(@NotNull TestRestTemplate template, @NotNull String title, @Nullable String xml) { + private URI addNewMap(@NotNull TestRestTemplate template, @NotNull String title, @Nullable String xml) throws URISyntaxException { // Create a new map ... final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_XML); - HttpEntity createUserEntity = new HttpEntity<>(xml, requestHeaders); - return template.postForLocation("/api/restful/maps?title=" + title, createUserEntity); + final HttpEntity createUserEntity = new HttpEntity<>(xml, requestHeaders); + + final ResponseEntity exchange = template.exchange("/api/restful/maps?title=" + title, HttpMethod.POST, createUserEntity, String.class); + assertTrue(exchange.getStatusCode().is2xxSuccessful()); + + final List locations = exchange.getHeaders().get(HttpHeaders.LOCATION); + return new URI(locations.stream().findFirst().get()); } - private URI addNewMap(@NotNull TestRestTemplate template, @NotNull String title) { + private URI addNewMap(@NotNull TestRestTemplate template, @NotNull String title) throws URISyntaxException { return addNewMap(template, title, null); } From 34318c1e3f70d1efd97eb384fedc0ac797802f32 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Fri, 9 Feb 2024 00:02:56 -0800 Subject: [PATCH 067/110] Fix json props. --- .../filter/JwtAuthenticationFilter.java | 4 +- .../model/CollaborationProperties.java | 37 ++++++++++--------- .../wisemapping/rest/MindmapController.java | 2 - .../rest/model/RestMindmapMetadata.java | 26 ++++++------- 4 files changed, 33 insertions(+), 36 deletions(-) diff --git a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java index fe462d9d..9b376273 100644 --- a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java +++ b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java @@ -25,6 +25,7 @@ import java.util.Optional; @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { private static final String BEARER_TOKEN_PREFIX = "Bearer "; + private static final String AUTHORIZATION_HEADER = "Authorization"; @Autowired private UserDetailsService userDetailsService; @@ -38,7 +39,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { throws ServletException, IOException { final Optional token = getJwtTokenFromRequest(request); - if (token.isPresent() && SecurityContextHolder.getContext().getAuthentication() == null) { // Extract email from token ... final Optional email = extractEmailFromToken(token.get()); @@ -74,7 +74,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private static Optional getJwtTokenFromRequest(@NotNull HttpServletRequest request) { Optional result = Optional.empty(); - final String authorizationHeader = request.getHeader("Authorization"); + final String authorizationHeader = request.getHeader(AUTHORIZATION_HEADER); if (authorizationHeader != null) { if (authorizationHeader.startsWith(BEARER_TOKEN_PREFIX)) { logger.trace("JWT Bearer token found."); diff --git a/wise-api/src/main/java/com/wisemapping/model/CollaborationProperties.java b/wise-api/src/main/java/com/wisemapping/model/CollaborationProperties.java index 155c4b82..5dc578e7 100644 --- a/wise-api/src/main/java/com/wisemapping/model/CollaborationProperties.java +++ b/wise-api/src/main/java/com/wisemapping/model/CollaborationProperties.java @@ -1,32 +1,33 @@ /* -* Copyright [2022] [wisemapping] -* -* Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the -* "powered by wisemapping" text requirement on every single page; -* you may not use this file except in compliance with the License. -* You may obtain a copy of the license at -* -* http://www.wisemapping.org/license -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.wisemapping.model; import org.jetbrains.annotations.NotNull; import jakarta.persistence.*; + import java.io.Serializable; @Entity @Table(name = "COLLABORATION_PROPERTIES") -public class CollaborationProperties implements Serializable { - public static final String DEFAULT_JSON_PROPERTIES = "{zoom:0.8}"; +public class CollaborationProperties implements Serializable { + public static final String DEFAULT_JSON_PROPERTIES = "{\"zoom\":0.8}"; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; diff --git a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java index b1d1df7d..2d308c2b 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java @@ -33,7 +33,6 @@ import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -206,7 +205,6 @@ public class MindmapController extends BaseController { return mindmapHistory.getUnzipXml(); } - /** * The intention of this method is the update of several properties at once ... */ diff --git a/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java b/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java index 050cf876..8b44850b 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java +++ b/wise-api/src/main/java/com/wisemapping/rest/model/RestMindmapMetadata.java @@ -35,6 +35,14 @@ public class RestMindmapMetadata { private String jsonProps; private boolean locked; private String title; + private String isLockedBy; + + public RestMindmapMetadata(@NotNull String title, @NotNull String jsonProps, boolean locked, @Nullable String isLockedBy) { + this.jsonProps = jsonProps; + this.title = title; + this.locked = locked; + this.isLockedBy = isLockedBy; + } public String getJsonProps() { return jsonProps; @@ -60,21 +68,11 @@ public class RestMindmapMetadata { this.title = title; } - public String getLockFullName() { - return lockFullName; + public String getIsLockedBy() { + return isLockedBy; } - public void setLockFullName(String lockFullName) { - this.lockFullName = lockFullName; + public void setIsLockedBy(String isLockedBy) { + this.isLockedBy = isLockedBy; } - - private String lockFullName; - - public RestMindmapMetadata(@NotNull String title, @NotNull String jsonProps, boolean locked, @Nullable String lockFullName) { - this.jsonProps = jsonProps; - this.title = title; - this.locked = locked; - this.lockFullName = lockFullName; - } - } From 555c6383b930418ed4ef86a0916eadb3e04b7961 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Fri, 9 Feb 2024 23:35:26 -0800 Subject: [PATCH 068/110] Fix location resolver. --- .../config/common/CommonConfig.java | 34 ++++++++++- .../config/rest/InterceptorsConfig.java | 8 +-- .../filter/UserLocaleInterceptor.java | 57 ------------------- wise-api/src/main/resources/application.yml | 0 .../resources/spring/wisemapping-messages.xml | 15 ----- 5 files changed, 35 insertions(+), 79 deletions(-) delete mode 100644 wise-api/src/main/java/com/wisemapping/filter/UserLocaleInterceptor.java mode change 100755 => 100644 wise-api/src/main/resources/application.yml delete mode 100755 wise-api/src/main/resources/spring/wisemapping-messages.xml diff --git a/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java index f945cbdf..43f06c96 100644 --- a/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java @@ -1,16 +1,48 @@ package com.wisemapping.config.common; import com.wisemapping.dao.LabelManagerImpl; +import com.wisemapping.model.User; import com.wisemapping.security.AuthenticationProvider; +import com.wisemapping.security.Utils; import com.wisemapping.service.MindmapServiceImpl; import com.wisemapping.util.VelocityEngineUtils; +import jakarta.servlet.http.HttpServletRequest; +import org.jetbrains.annotations.Nullable; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.ImportResource; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; + +import java.util.Locale; @ComponentScan(basePackageClasses = {AuthenticationProvider.class, MindmapServiceImpl.class, LabelManagerImpl.class, VelocityEngineUtils.class}) @Import({JPAConfig.class, SecurityConfig.class}) @EnableAutoConfiguration public class CommonConfig { + @Bean + public LocaleResolver localeResolver() { + final LocaleResolver localeResolver = new AcceptHeaderLocaleResolver() { + @Override + public Locale resolveLocale(@Nullable HttpServletRequest request) { + final User user = Utils.getUser(); + Locale result; + String locale = user.getLocale(); + if (user != null && locale != null) { + final String locales[] = locale.split("_"); + Locale.Builder builder = new Locale.Builder().setLanguage(locales[0]); + if (locales.length > 1) { + builder.setVariant(locales[1]); + } + result = builder.build(); + } else { + result = super.resolveLocale(request); + } + return result; + } + }; + return localeResolver; + } } + diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/InterceptorsConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/InterceptorsConfig.java index ac1c9784..e521b7ea 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/InterceptorsConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/InterceptorsConfig.java @@ -18,7 +18,6 @@ package com.wisemapping.config.rest; import com.wisemapping.filter.RequestPropertiesInterceptor; -import com.wisemapping.filter.UserLocaleInterceptor; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; @@ -27,17 +26,14 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration -@ComponentScan(basePackageClasses = UserLocaleInterceptor.class) +@ComponentScan(basePackageClasses = RequestPropertiesInterceptor.class) public class InterceptorsConfig implements WebMvcConfigurer { - @Autowired - private UserLocaleInterceptor userLocaleInterceptor; - @Autowired private RequestPropertiesInterceptor requestPropertiesInterceptor; @Override public void addInterceptors(@NotNull final InterceptorRegistry registry) { - registry.addInterceptor(userLocaleInterceptor); registry.addInterceptor(requestPropertiesInterceptor); } + } \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/filter/UserLocaleInterceptor.java b/wise-api/src/main/java/com/wisemapping/filter/UserLocaleInterceptor.java deleted file mode 100644 index 6b4abe1f..00000000 --- a/wise-api/src/main/java/com/wisemapping/filter/UserLocaleInterceptor.java +++ /dev/null @@ -1,57 +0,0 @@ -/* -* Copyright [2022] [wisemapping] -* -* Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the -* "powered by wisemapping" text requirement on every single page; -* you may not use this file except in compliance with the License. -* You may obtain a copy of the license at -* -* http://www.wisemapping.org/license -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.wisemapping.filter; - -import com.wisemapping.model.User; -import com.wisemapping.security.Utils; -import org.jetbrains.annotations.NotNull; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.i18n.SessionLocaleResolver; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.http.HttpSession; -import java.util.Locale; -@Component -public class UserLocaleInterceptor implements HandlerInterceptor { - - @Override - public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, Object object) throws Exception { - - final HttpSession session = request.getSession(false); - User user = Utils.getUser(false); - - if (user != null && session != null) { - String userLocale = user.getLocale(); - final Locale sessionLocale = (Locale) session.getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME); - if ((userLocale != null) && ((sessionLocale == null) || (!userLocale.equals(sessionLocale.toString())))) { - Locale locale; - if (userLocale.contains("_")) { - final String[] spit = userLocale.split("_"); - locale = new Locale(spit[0], spit[1]); - } else { - locale = new Locale(userLocale); - } - session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, locale); - } - } - return true; - } -} diff --git a/wise-api/src/main/resources/application.yml b/wise-api/src/main/resources/application.yml old mode 100755 new mode 100644 diff --git a/wise-api/src/main/resources/spring/wisemapping-messages.xml b/wise-api/src/main/resources/spring/wisemapping-messages.xml deleted file mode 100755 index 7cebddbe..00000000 --- a/wise-api/src/main/resources/spring/wisemapping-messages.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - messages - - - - From 6f528835bfd9035e6da56fee71c4f67f6a13e92d Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Fri, 9 Feb 2024 23:55:05 -0800 Subject: [PATCH 069/110] Fix try access. --- .../main/java/com/wisemapping/config/rest/RestAppConfig.java | 3 ++- .../src/main/java/com/wisemapping/rest/MindmapController.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index 65546bd1..918d1278 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -39,8 +39,9 @@ public class RestAppConfig { .securityMatcher("/**") .addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests(auth -> auth - .requestMatchers(mvc.pattern("/api/restful/users/")).permitAll() .requestMatchers(mvc.pattern("/api/restful/authenticate")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/users/")).permitAll() + .requestMatchers(mvc.pattern("/api/restful/maps/*/document/xml-pub")).permitAll() .requestMatchers(mvc.pattern("/api/restful/users/resetPassword")).permitAll() .requestMatchers(mvc.pattern("/api/restful/oauth2/googlecallback")).permitAll() .requestMatchers(mvc.pattern("/api/restful/oauth2/confirmaccountsync")).permitAll() diff --git a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java index 2d308c2b..276e20aa 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java @@ -250,7 +250,7 @@ public class MindmapController extends BaseController { @NotNull private Mindmap findMindmapById(int id) throws MapCouldNotFoundException, AccessDeniedSecurityException { // Has enough permissions ? - final User user = Utils.getUser(true); + final User user = Utils.getUser(); if (!mindmapService.hasPermissions(user, id, CollaborationRole.VIEWER)) { throw new AccessDeniedSecurityException(id, user); } From f8b8aea9014879b83a6b29139de435300558d6fb Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sat, 10 Feb 2024 13:53:44 -0800 Subject: [PATCH 070/110] Add support for configure http basic. --- .../config/common/CommonConfig.java | 12 +++++----- .../config/rest/RestAppConfig.java | 17 ++++++++++---- .../filter/SupportedUserAgent.java | 23 ------------------- .../wisemapping/rest/MindmapController.java | 12 +++++----- .../wisemapping/service/HibernateUtil.java | 1 - .../service/NotificationService.java | 3 +-- wise-api/src/main/resources/application.yml | 2 ++ .../test/rest/RestAccountControllerTest.java | 6 ++++- .../test/rest/RestJwtAuthControllerTest.java | 5 +++- .../test/rest/RestLabelControllerTest.java | 5 +++- .../test/rest/RestMindmapControllerTest.java | 5 +++- .../test/rest/RestUserControllerTest.java | 5 +++- 12 files changed, 49 insertions(+), 47 deletions(-) delete mode 100644 wise-api/src/main/java/com/wisemapping/filter/SupportedUserAgent.java diff --git a/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java index 43f06c96..561fce36 100644 --- a/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java @@ -7,7 +7,7 @@ import com.wisemapping.security.Utils; import com.wisemapping.service.MindmapServiceImpl; import com.wisemapping.util.VelocityEngineUtils; import jakarta.servlet.http.HttpServletRequest; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -23,14 +23,15 @@ import java.util.Locale; public class CommonConfig { @Bean public LocaleResolver localeResolver() { - final LocaleResolver localeResolver = new AcceptHeaderLocaleResolver() { + return new AcceptHeaderLocaleResolver() { @Override - public Locale resolveLocale(@Nullable HttpServletRequest request) { + public Locale resolveLocale(@NotNull HttpServletRequest request) { final User user = Utils.getUser(); Locale result; - String locale = user.getLocale(); - if (user != null && locale != null) { + if (user != null && user.getLocale() != null) { + String locale = user.getLocale(); final String locales[] = locale.split("_"); + Locale.Builder builder = new Locale.Builder().setLanguage(locales[0]); if (locales.length > 1) { builder.setVariant(locales[1]); @@ -42,7 +43,6 @@ public class CommonConfig { return result; } }; - return localeResolver; } } diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index 918d1278..ada33915 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -5,6 +5,7 @@ import com.wisemapping.rest.MindmapController; import jakarta.servlet.http.HttpServletResponse; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -25,6 +26,9 @@ import static org.springframework.security.config.Customizer.withDefaults; @EnableWebSecurity public class RestAppConfig { + @Value("${app.api.http-basic-enabled:false}") + private boolean enableHttpBasic; + @Autowired private JwtAuthenticationFilter jwtAuthenticationFilter; @@ -35,7 +39,7 @@ public class RestAppConfig { @Bean SecurityFilterChain apiSecurityFilterChain(@NotNull final HttpSecurity http, @NotNull final MvcRequestMatcher.Builder mvc) throws Exception { - return http + http .securityMatcher("/**") .addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests(auth -> auth @@ -54,8 +58,13 @@ public class RestAppConfig { response.setStatus(HttpServletResponse.SC_OK); })) .csrf(AbstractHttpConfigurer::disable) - .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - .httpBasic(withDefaults()) - .build(); + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); + + // Http basic is mainly used by automation tests. + if (enableHttpBasic) { + http.httpBasic(withDefaults()); + } + + return http.build(); } } diff --git a/wise-api/src/main/java/com/wisemapping/filter/SupportedUserAgent.java b/wise-api/src/main/java/com/wisemapping/filter/SupportedUserAgent.java deleted file mode 100644 index 13919387..00000000 --- a/wise-api/src/main/java/com/wisemapping/filter/SupportedUserAgent.java +++ /dev/null @@ -1,23 +0,0 @@ -/* -* Copyright [2022] [wisemapping] -* -* Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the -* "powered by wisemapping" text requirement on every single page; -* you may not use this file except in compliance with the License. -* You may obtain a copy of the license at -* -* http://www.wisemapping.org/license -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.wisemapping.filter; - -public interface SupportedUserAgent{ - String USER_AGENT_HEADER = "User-Agent"; -} diff --git a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java index 276e20aa..c69f0cbf 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/MindmapController.java @@ -225,7 +225,7 @@ public class MindmapController extends BaseController { final String title = restMindmap.getTitle(); if (title != null && !title.equals(mindmap.getTitle())) { if (mindmapService.getMindmapByTitle(title, user) != null) { - throw buildValidationException("title", "You already have a map with this title"); + throw buildValidationException("You already have a map with this title"); } mindmap.setTitle(title); } @@ -273,7 +273,7 @@ public class MindmapController extends BaseController { // Is there a map with the same name ? if (mindmapService.getMindmapByTitle(title, user) != null) { - throw buildValidationException("title", "You already have a mindmap with this title"); + throw buildValidationException("You already have a mindmap with this title"); } // Update map ... @@ -497,7 +497,7 @@ public class MindmapController extends BaseController { // Update map status ... final boolean starred = Boolean.parseBoolean(value); final Optional collaboration = mindmap.findCollaboration(user); - if (!collaboration.isPresent()) { + if (collaboration.isEmpty()) { throw new WiseMappingException("No enough permissions."); } collaboration.get().getCollaborationProperties().setStarred(starred); @@ -512,7 +512,7 @@ public class MindmapController extends BaseController { final User user = Utils.getUser(); final Optional collaboration = mindmap.findCollaboration(user); - if (!collaboration.isPresent()) { + if (collaboration.isEmpty()) { throw new WiseMappingException("No enough permissions."); } boolean result = collaboration.get().getCollaborationProperties().getStarred(); @@ -659,9 +659,9 @@ public class MindmapController extends BaseController { mindmapService.updateMindmap(mindMap, !minor); } - private ValidationException buildValidationException(@NotNull String fieldName, @NotNull String message) throws WiseMappingException { + private ValidationException buildValidationException(@NotNull String message) throws WiseMappingException { final BindingResult result = new BeanPropertyBindingResult(new RestMindmap(), ""); - result.rejectValue(fieldName, "error.not-specified", null, message); + result.rejectValue("title", "error.not-specified", null, message); return new ValidationException(result); } diff --git a/wise-api/src/main/java/com/wisemapping/service/HibernateUtil.java b/wise-api/src/main/java/com/wisemapping/service/HibernateUtil.java index 600b3305..92e969e5 100755 --- a/wise-api/src/main/java/com/wisemapping/service/HibernateUtil.java +++ b/wise-api/src/main/java/com/wisemapping/service/HibernateUtil.java @@ -22,7 +22,6 @@ import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { - private static final SessionFactory sessionFactory; static { diff --git a/wise-api/src/main/java/com/wisemapping/service/NotificationService.java b/wise-api/src/main/java/com/wisemapping/service/NotificationService.java index 81e4f24e..4534df18 100644 --- a/wise-api/src/main/java/com/wisemapping/service/NotificationService.java +++ b/wise-api/src/main/java/com/wisemapping/service/NotificationService.java @@ -18,7 +18,6 @@ package com.wisemapping.service; -import com.wisemapping.filter.SupportedUserAgent; import com.wisemapping.model.Collaboration; import com.wisemapping.model.Mindmap; import com.wisemapping.model.User; @@ -202,7 +201,7 @@ final public class NotificationService { final String userEmail = user != null ? user.getEmail() : "'anonymous'"; model.put("email", userEmail); - model.put("userAgent", request.getHeader(SupportedUserAgent.USER_AGENT_HEADER)); + model.put("userAgent", request.getHeader("User-Agent")); model.put("server", request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()); model.put("requestURI", request.getRequestURI()); model.put("method", request.getMethod()); diff --git a/wise-api/src/main/resources/application.yml b/wise-api/src/main/resources/application.yml index 12e87cc1..38d3c5c5 100644 --- a/wise-api/src/main/resources/application.yml +++ b/wise-api/src/main/resources/application.yml @@ -50,6 +50,8 @@ logging: # Application Configuration. app: + api: + http-basic-enabled: false jwt: secret: dlqxKAg685SaKhsQXIMeM=JWCw3bkl3Ei3Tb7LMlnd19oMd66burPNlJ0Po1qguyjgpakQTk2CN3 expirationMin: 10080 # One week diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java index 9d94943f..04b673ca 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestAccountControllerTest.java @@ -40,7 +40,11 @@ import static com.wisemapping.test.rest.RestHelper.*; import static org.junit.jupiter.api.Assertions.*; -@SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, MindmapController.class, AdminController.class, UserController.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest( + classes = {RestAppConfig.class, CommonConfig.class, MindmapController.class, AdminController.class, UserController.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = {"app.api.http-basic-enabled=true"} +) @AutoConfigureMockMvc public class RestAccountControllerTest { private static final String ADMIN_USER = "admin@wisemapping.org"; diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java index 1159e4d3..cc401536 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestJwtAuthControllerTest.java @@ -38,7 +38,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, JwtAuthController.class}) +@SpringBootTest( + classes = {RestAppConfig.class, CommonConfig.class, JwtAuthController.class}, + properties = {"app.api.http-basic-enabled=true"} +) @AutoConfigureMockMvc public class RestJwtAuthControllerTest { diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestLabelControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestLabelControllerTest.java index bd3ed821..2a77c464 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestLabelControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestLabelControllerTest.java @@ -28,7 +28,10 @@ import static com.wisemapping.test.rest.RestHelper.createHeaders; import static org.junit.jupiter.api.Assertions.*; -@SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, LabelController.class, AdminController.class, UserController.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest( + classes = {RestAppConfig.class, CommonConfig.class, LabelController.class, AdminController.class, UserController.class}, + properties = {"app.api.http-basic-enabled=true"}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class RestLabelControllerTest { private static final String COLOR = "#000000"; diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java index 6e01a87a..55e42408 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestMindmapControllerTest.java @@ -31,7 +31,10 @@ import java.util.stream.Collectors; import static com.wisemapping.test.rest.RestHelper.createHeaders; import static org.junit.jupiter.api.Assertions.*; -@SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, MindmapController.class, AdminController.class, UserController.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest( + classes = {RestAppConfig.class, CommonConfig.class, MindmapController.class, AdminController.class, UserController.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = {"app.api.http-basic-enabled=true"}) public class RestMindmapControllerTest { private RestUser user; diff --git a/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java index 73fe8128..7baae30e 100644 --- a/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java +++ b/wise-api/src/test/java/com/wisemapping/test/rest/RestUserControllerTest.java @@ -45,7 +45,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, UserController.class}) +@SpringBootTest( + classes = {RestAppConfig.class, CommonConfig.class, UserController.class}, + properties = {"app.api.http-basic-enabled=true"} +) @AutoConfigureMockMvc public class RestUserControllerTest { From eaf03ea28d8b7f613b9d144085cdac63a4526bfd Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sun, 11 Feb 2024 12:21:38 -0800 Subject: [PATCH 071/110] Clean up. --- .../config/rest/InterceptorsConfig.java | 39 --------- .../config/rest/RestAppConfig.java | 9 +- .../com/wisemapping/filter/CorsFilter.java | 79 ----------------- .../filter/JwtAuthenticationFilter.java | 12 +-- .../filter/RequestPropertiesInterceptor.java | 83 ------------------ .../main/java/com/wisemapping/model/User.java | 2 +- .../wisemapping/rest/JwtAuthController.java | 60 +++++-------- .../wisemapping/rest/OAuth2Controller.java | 84 +++++++++---------- .../wisemapping/security/JwtTokenUtil.java | 20 +++++ .../com/wisemapping/service/UserService.java | 2 +- .../wisemapping/service/UserServiceImpl.java | 7 +- .../service/google/GoogleService.java | 17 ++-- .../webmvc/MvcLoginController.java | 46 ---------- wise-api/src/main/resources/application.yml | 27 +++--- 14 files changed, 119 insertions(+), 368 deletions(-) delete mode 100644 wise-api/src/main/java/com/wisemapping/config/rest/InterceptorsConfig.java delete mode 100644 wise-api/src/main/java/com/wisemapping/filter/CorsFilter.java delete mode 100644 wise-api/src/main/java/com/wisemapping/filter/RequestPropertiesInterceptor.java delete mode 100644 wise-api/src/main/java/com/wisemapping/webmvc/MvcLoginController.java diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/InterceptorsConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/InterceptorsConfig.java deleted file mode 100644 index e521b7ea..00000000 --- a/wise-api/src/main/java/com/wisemapping/config/rest/InterceptorsConfig.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright [2022] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.wisemapping.config.rest; - -import com.wisemapping.filter.RequestPropertiesInterceptor; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -@ComponentScan(basePackageClasses = RequestPropertiesInterceptor.class) -public class InterceptorsConfig implements WebMvcConfigurer { - @Autowired - private RequestPropertiesInterceptor requestPropertiesInterceptor; - - @Override - public void addInterceptors(@NotNull final InterceptorRegistry registry) { - registry.addInterceptor(requestPropertiesInterceptor); - } - -} \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java index ada33915..a55e0142 100644 --- a/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/rest/RestAppConfig.java @@ -8,7 +8,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; 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.configurers.AbstractHttpConfigurer; @@ -21,8 +20,7 @@ import org.springframework.web.servlet.handler.HandlerMappingIntrospector; import static org.springframework.security.config.Customizer.withDefaults; -@SpringBootApplication(scanBasePackageClasses = MindmapController.class) -@Import({InterceptorsConfig.class}) +@SpringBootApplication(scanBasePackageClasses = {MindmapController.class, JwtAuthenticationFilter.class}) @EnableWebSecurity public class RestAppConfig { @@ -43,12 +41,13 @@ public class RestAppConfig { .securityMatcher("/**") .addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests(auth -> auth + .requestMatchers(mvc.pattern("/error")).permitAll() .requestMatchers(mvc.pattern("/api/restful/authenticate")).permitAll() .requestMatchers(mvc.pattern("/api/restful/users/")).permitAll() .requestMatchers(mvc.pattern("/api/restful/maps/*/document/xml-pub")).permitAll() .requestMatchers(mvc.pattern("/api/restful/users/resetPassword")).permitAll() - .requestMatchers(mvc.pattern("/api/restful/oauth2/googlecallback")).permitAll() - .requestMatchers(mvc.pattern("/api/restful/oauth2/confirmaccountsync")).permitAll() + .requestMatchers(mvc.pattern("/api/oauth2/googlecallback")).permitAll() + .requestMatchers(mvc.pattern("/api/oauth2/confirmaccountsync")).permitAll() .requestMatchers(mvc.pattern("/api/restful/admin/**")).hasAnyRole("ADMIN") .requestMatchers(mvc.pattern("/**")).hasAnyRole("USER", "ADMIN") .anyRequest().authenticated() diff --git a/wise-api/src/main/java/com/wisemapping/filter/CorsFilter.java b/wise-api/src/main/java/com/wisemapping/filter/CorsFilter.java deleted file mode 100644 index fd0d53b9..00000000 --- a/wise-api/src/main/java/com/wisemapping/filter/CorsFilter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* -* Copyright [2022] [wisemapping] -* -* Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the -* "powered by wisemapping" text requirement on every single page; -* you may not use this file except in compliance with the License. -* You may obtain a copy of the license at -* -* http://www.wisemapping.org/license -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.wisemapping.filter; - -import java.io.IOException; - -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.FilterConfig; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; -import jakarta.servlet.http.HttpServletResponse; - -/** - * - * If your wisemapping customization throws cross domain errores in browser, you can configure this filter in webdefault.xml - * By default it will accept all domains, but you can restrict to the domain you need - * - * - * cross-origin - * com.wisemapping.filter.CorsFilter - * - * allowedOrigins - * * - * - * - * allowedMethods - * GET,POST,HEAD - * - * - * allowedHeaders - * X-Requested-With,Content-Type,Accept,Origin - * - * - * - * cross-origin - * /* - * - * - */ -public class CorsFilter implements Filter { - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - } - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) - throws IOException, ServletException { - if (servletResponse != null) { - // Authorize (allow) all domains to consume the content - ((HttpServletResponse) servletResponse).addHeader("Access-Control-Allow-Origin", "*"); - ((HttpServletResponse) servletResponse).addHeader("Access-Control-Allow-Methods","GET, OPTIONS, HEAD, PUT, POST"); - } - - chain.doFilter(servletRequest, servletResponse); - } - - @Override - public void destroy() { - } -} diff --git a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java index 9b376273..927cb650 100644 --- a/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java +++ b/wise-api/src/main/java/com/wisemapping/filter/JwtAuthenticationFilter.java @@ -11,7 +11,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; +import org.springframework.http.HttpHeaders; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -22,10 +22,10 @@ import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; import java.util.Optional; +import static com.wisemapping.security.JwtTokenUtil.BEARER_TOKEN_PREFIX; + @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { - private static final String BEARER_TOKEN_PREFIX = "Bearer "; - private static final String AUTHORIZATION_HEADER = "Authorization"; @Autowired private UserDetailsService userDetailsService; @@ -35,7 +35,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { final private static Logger logger = LogManager.getLogger(); @Override - protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) + protected void doFilterInternal(@NotNull final HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException { final Optional token = getJwtTokenFromRequest(request); @@ -62,7 +62,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private Optional extractEmailFromToken(final @NotNull String token) { Optional result = Optional.empty(); try { - result = Optional.of(jwtTokenUtil.extractFromJwtToken(token)); + result = Optional.ofNullable(jwtTokenUtil.extractFromJwtToken(token)); } catch (Exception e) { // Handle token extraction/validation errors logger.debug("Error extracting email from token: " + e.getMessage()); @@ -74,7 +74,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private static Optional getJwtTokenFromRequest(@NotNull HttpServletRequest request) { Optional result = Optional.empty(); - final String authorizationHeader = request.getHeader(AUTHORIZATION_HEADER); + final String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION); if (authorizationHeader != null) { if (authorizationHeader.startsWith(BEARER_TOKEN_PREFIX)) { logger.trace("JWT Bearer token found."); diff --git a/wise-api/src/main/java/com/wisemapping/filter/RequestPropertiesInterceptor.java b/wise-api/src/main/java/com/wisemapping/filter/RequestPropertiesInterceptor.java deleted file mode 100644 index 9c222c77..00000000 --- a/wise-api/src/main/java/com/wisemapping/filter/RequestPropertiesInterceptor.java +++ /dev/null @@ -1,83 +0,0 @@ -/* -* Copyright [2022] [wisemapping] -* -* Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the -* "powered by wisemapping" text requirement on every single page; -* you may not use this file except in compliance with the License. -* You may obtain a copy of the license at -* -* http://www.wisemapping.org/license -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.wisemapping.filter; - -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - - -@Component -public class RequestPropertiesInterceptor implements HandlerInterceptor { - @Value("${google.analytics.enabled}") - private Boolean analyticsEnabled; - - @Value("${google.analytics.account}") - private String analyticsAccount; - - @Value("${google.recaptcha2.enabled}") - private Boolean recaptcha2Enabled; - - @Value("${site.static.js.url}") - private String siteStaticUrl; - - @Value("${google.recaptcha2.siteKey}") - private String recaptcha2SiteKey; - - @Value("${google.ads.enabled}") - private Boolean adsEnabled; - - @Value("${site.homepage}") - private String siteHomepage; - - @Value("${site.baseurl:}") - private String siteUrl; - - @Value("${security.oauth2.google.url}") - private String googleOauth2Url; - - @Override - public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, Object object) throws Exception { - - request.setAttribute("google.analytics.enabled", analyticsEnabled); - request.setAttribute("google.analytics.account", analyticsAccount); - request.setAttribute("google.ads.enabled", adsEnabled); - - request.setAttribute("google.recaptcha2.enabled", recaptcha2Enabled); - request.setAttribute("google.recaptcha2.siteKey", recaptcha2SiteKey); - - request.setAttribute("security.oauth2.google.url", googleOauth2Url); - - request.setAttribute("site.homepage", siteHomepage); - request.setAttribute("site.static.js.url", siteStaticUrl); - - request.setAttribute("security.type", "db"); - - // If the property could not be resolved, try to infer one from the request... - if (siteUrl.isBlank()) { - siteUrl = request.getRequestURL().toString().replace(request.getRequestURI(), request.getContextPath()); - } - request.setAttribute("site.baseurl", siteUrl); - return true; - } -} diff --git a/wise-api/src/main/java/com/wisemapping/model/User.java b/wise-api/src/main/java/com/wisemapping/model/User.java index 39f6e8a1..2d2b6a21 100644 --- a/wise-api/src/main/java/com/wisemapping/model/User.java +++ b/wise-api/src/main/java/com/wisemapping/model/User.java @@ -164,7 +164,7 @@ public class User } public Boolean getGoogleSync() { - return googleSync; + return googleSync!=null && googleSync; } public void setGoogleSync(Boolean googleSync) { diff --git a/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java index 879ec8a1..01202552 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java +++ b/wise-api/src/main/java/com/wisemapping/rest/JwtAuthController.java @@ -18,64 +18,44 @@ package com.wisemapping.rest; +import com.wisemapping.exceptions.WiseMappingException; import com.wisemapping.rest.model.RestJwtUser; import com.wisemapping.security.JwtTokenUtil; -import com.wisemapping.security.UserDetailsService; import jakarta.servlet.http.HttpServletResponse; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.DisabledException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @CrossOrigin @RequestMapping("/api/restful") public class JwtAuthController { - @Autowired - private AuthenticationManager authenticationManager; + @Autowired + private AuthenticationManager authenticationManager; - @Autowired - private UserDetailsService userDetailsService; + @Autowired + private JwtTokenUtil jwtTokenUtil; - @Autowired - private JwtTokenUtil jwtTokenUtil; + @RequestMapping(value = "/authenticate", method = RequestMethod.POST) + public ResponseEntity createAuthenticationToken(@RequestBody RestJwtUser user, @NotNull HttpServletResponse response) throws WiseMappingException { + // Is a valid user ? + authenticate(user.getEmail(), user.getPassword()); + final String result = jwtTokenUtil.doLogin(response, user.getEmail()); - @RequestMapping(value = "/authenticate", method = RequestMethod.POST) - public ResponseEntity createAuthenticationToken(@RequestBody RestJwtUser user, @NotNull HttpServletResponse response) throws Exception { + return ResponseEntity.ok(result); + } - // Is a valid user ? - authenticate(user.getEmail(), user.getPassword()); - - // Create token ... - final UserDetails userDetails = userDetailsService - .loadUserByUsername(user.getEmail()); - - final String token = jwtTokenUtil.generateJwtToken(userDetails); - - // Add token in the header ... - response.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token); - - return ResponseEntity.ok(token); - } - - private void authenticate(@NotNull String username, @NotNull String password) throws Exception { - try { - authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); - } catch (DisabledException e) { - throw new Exception("USER_DISABLED", e); - } catch (BadCredentialsException e) { - throw new Exception("INVALID_CREDENTIALS", e); - } - } + private void authenticate(@NotNull String username, @NotNull String password) throws WiseMappingException { + try { + authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); + } catch (DisabledException | BadCredentialsException e) { + throw new WiseMappingException(e.getMessage(), e); + } + } } \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/rest/OAuth2Controller.java b/wise-api/src/main/java/com/wisemapping/rest/OAuth2Controller.java index 7427070d..25bc74ef 100644 --- a/wise-api/src/main/java/com/wisemapping/rest/OAuth2Controller.java +++ b/wise-api/src/main/java/com/wisemapping/rest/OAuth2Controller.java @@ -21,68 +21,60 @@ package com.wisemapping.rest; import com.wisemapping.exceptions.WiseMappingException; import com.wisemapping.model.User; import com.wisemapping.rest.model.RestOath2CallbackResponse; -import com.wisemapping.service.*; +import com.wisemapping.security.JwtTokenUtil; +import com.wisemapping.service.UserService; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpSession; - @RestController +@RequestMapping("/api/oauth2/") @CrossOrigin public class OAuth2Controller extends BaseController { - @Qualifier("userService") - @Autowired - private UserService userService; + @Qualifier("userService") + @Autowired + private UserService userService; - @Qualifier("authenticationManager") - @Autowired - private AuthenticationManager authManager; + @Qualifier("authenticationManager") + @Autowired + private AuthenticationManager authManager; - @Value("${google.recaptcha2.enabled}") - private Boolean recatchaEnabled; + @Autowired + private JwtTokenUtil jwtTokenUtil; - @Value("${accounts.exclusion.domain:''}") - private String domainBanExclusion; - private void doLogin(HttpServletRequest request, String email) { - PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken(email,null); - Authentication auth = authManager.authenticate(token); - SecurityContextHolder.getContext().setAuthentication(auth); - // update spring mvc session - HttpSession session = request.getSession(true); - session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext()); - } + @RequestMapping(method = RequestMethod.POST, value = "googlecallback", produces = {"application/json"}) + @ResponseStatus(value = HttpStatus.OK) + public RestOath2CallbackResponse processGoogleCallback(@NotNull @RequestParam String code, @NotNull HttpServletResponse response, @NotNull HttpServletRequest request) throws WiseMappingException { + User user = userService.createAndAuthUserFromGoogle(code); + if (user.getGoogleSync()) { + jwtTokenUtil.doLogin(response, user.getEmail()); + } - @RequestMapping(method = RequestMethod.POST, value = "/oauth2/googlecallback", produces = { "application/json" }) - @ResponseStatus(value = HttpStatus.OK) - public RestOath2CallbackResponse processGoogleCallback(@NotNull @RequestParam String code, @NotNull HttpServletRequest request) throws WiseMappingException { - User user = userService.createUserFromGoogle(code); - if (user.getGoogleSync() != null && user.getGoogleSync()) { - doLogin(request, user.getEmail()); - } - RestOath2CallbackResponse response = new RestOath2CallbackResponse(); - response.setEmail(user.getEmail()); - response.setGoogleSync(user.getGoogleSync()); - response.setSyncCode(user.getSyncCode()); - return response; - } + // Response ... + final RestOath2CallbackResponse result = new RestOath2CallbackResponse(); + result.setEmail(user.getEmail()); + result.setGoogleSync(user.getGoogleSync()); + result.setSyncCode(user.getSyncCode()); + return result; + } - @RequestMapping(method = RequestMethod.PUT, value = "/oauth2/confirmaccountsync", produces = { "application/json" }) - @ResponseStatus(value = HttpStatus.OK) - public void confirmAccountSync(@NotNull @RequestParam String email, @NotNull @RequestParam String code, @NotNull HttpServletRequest request) throws WiseMappingException { - userService.confirmAccountSync(email, code); - doLogin(request, email); - } + @RequestMapping(method = RequestMethod.PUT, value = "confirmaccountsync", produces = {"application/json"}) + @ResponseStatus(value = HttpStatus.OK) + public void confirmAccountSync(@NotNull @RequestParam String email, @NotNull @RequestParam String code, @NotNull HttpServletResponse response) throws WiseMappingException { + // Authenticate ... + userService.createAndAuthUserFromGoogle(code); + // Update login + userService.confirmAccountSync(email, code); + + // Add header ... + jwtTokenUtil.doLogin(response, email); + } } diff --git a/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java index c33b7472..ef710352 100644 --- a/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java +++ b/wise-api/src/main/java/com/wisemapping/security/JwtTokenUtil.java @@ -3,11 +3,14 @@ package com.wisemapping.security; import io.jsonwebtoken.*; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; +import jakarta.servlet.http.HttpServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; @@ -18,6 +21,8 @@ import java.util.Date; @Component public class JwtTokenUtil implements Serializable { final private Logger logger = LogManager.getLogger(); + public final static String BEARER_TOKEN_PREFIX = "Bearer "; + @Value("${app.jwt.secret}") private String jwtSecret; @@ -25,6 +30,10 @@ public class JwtTokenUtil implements Serializable { @Value("${app.jwt.expirationMin}") private int jwtExpirationMin; + @Autowired + private UserDetailsService userDetailsService; + + public String generateJwtToken(@NotNull final UserDetails user) { return Jwts.builder() .setSubject((user.getUsername())) @@ -63,4 +72,15 @@ public class JwtTokenUtil implements Serializable { logger.trace("Is JWT token valid:" + result); return result; } + + @NotNull + public String doLogin(@NotNull HttpServletResponse response, @NotNull String email) { + final UserDetails userDetails = userDetailsService.loadUserByUsername(email); + + // Add JWT in the HTTP header ... + final String token = generateJwtToken(userDetails); + response.addHeader(HttpHeaders.AUTHORIZATION, BEARER_TOKEN_PREFIX + token); + + return token; + } } \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/service/UserService.java b/wise-api/src/main/java/com/wisemapping/service/UserService.java index 6fbda735..46f995b4 100755 --- a/wise-api/src/main/java/com/wisemapping/service/UserService.java +++ b/wise-api/src/main/java/com/wisemapping/service/UserService.java @@ -30,7 +30,7 @@ public interface UserService { User createUser(@NotNull User user, boolean emailConfirmEnabled, boolean welcomeEmail) throws WiseMappingException; - User createUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException; + User createAndAuthUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException; User confirmAccountSync(@NotNull String email, @NotNull String code) throws WiseMappingException; diff --git a/wise-api/src/main/java/com/wisemapping/service/UserServiceImpl.java b/wise-api/src/main/java/com/wisemapping/service/UserServiceImpl.java index 60cd0b44..bce28ff8 100755 --- a/wise-api/src/main/java/com/wisemapping/service/UserServiceImpl.java +++ b/wise-api/src/main/java/com/wisemapping/service/UserServiceImpl.java @@ -161,7 +161,6 @@ public class UserServiceImpl final Mindmap mindMap = buildTutorialMindmap(user.getFirstname()); mindmapService.addMindmap(mindMap, user); - // Send registration email. if (emailConfirmEnabled) { notificationService.sendRegistrationEmail(user); @@ -174,7 +173,7 @@ public class UserServiceImpl } @NotNull - public User createUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException { + public User createAndAuthUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException { GoogleAccountBasicData data; try { data = googleService.processCallback(callbackCode); @@ -185,7 +184,7 @@ public class UserServiceImpl User existingUser = userManager.getUserBy(data.getEmail()); if (existingUser == null) { User newUser = new User(); - // new registrations from google starts synched + // new registrations from google starts sync newUser.setGoogleSync(true); newUser.setEmail(data.getEmail()); newUser.setFirstname(data.getName()); @@ -208,7 +207,7 @@ public class UserServiceImpl } public User confirmAccountSync(@NotNull String email, @NotNull String code) throws WiseMappingException { - User existingUser = userManager.getUserBy(email); + final User existingUser = userManager.getUserBy(email); // additional security check if (existingUser == null || !existingUser.getSyncCode().equals(code)) { throw new WiseMappingException("User not found / incorrect code"); diff --git a/wise-api/src/main/java/com/wisemapping/service/google/GoogleService.java b/wise-api/src/main/java/com/wisemapping/service/google/GoogleService.java index 8bbb6267..6dbe36d0 100644 --- a/wise-api/src/main/java/com/wisemapping/service/google/GoogleService.java +++ b/wise-api/src/main/java/com/wisemapping/service/google/GoogleService.java @@ -34,15 +34,15 @@ import com.wisemapping.service.google.http.HttpInvokerException; public class GoogleService { @Autowired private HttpInvoker httpInvoker; - @Value("${security.oauth2.google.confirmUrl:}") + @Value("${app.security.oauth2.google.confirmUrl:}") private String optinConfirmUrl; - @Value("${security.oauth2.google.userinfoUrl:}") + @Value("${app.security.oauth2.google.userinfoUrl:}") private String accountBasicDataUrl; - @Value("${security.oauth2.google.clientId:}") + @Value("${app.security.oauth2.google.clientId:}") private String clientId; - @Value("${security.oauth2.google.clientSecret:}") + @Value("${app.security.oauth2.google.clientSecret:}") private String clientSecret; - @Value("${security.oauth2.google.callbackUrl:}") + @Value("${app.security.oauth2.google.callbackUrl:}") private String callbackUrl; public void setHttpInvoker(HttpInvoker httpInvoker) { @@ -108,8 +108,9 @@ public class GoogleService { public GoogleAccountBasicData processCallback(final String code) throws HttpInvokerException { - Map body = this.getOptinConfirmBody(code); - JsonNode optionConfirmResponse = httpInvoker.invoke( + + final Map body = this.getOptinConfirmBody(code); + final JsonNode optionConfirmResponse = httpInvoker.invoke( optinConfirmUrl, HttpInvokerContentType.FORM_ENCODED, HttpMethod.POST, @@ -120,7 +121,7 @@ public class GoogleService { final String accessToken = getNodeAsString(optionConfirmResponse, "access_token"); final String refreshToken = getNodeAsString(optionConfirmResponse, "refresh_token"); - GoogleAccountBasicData data = this.getAccountBasicData(accessToken); + final GoogleAccountBasicData data = this.getAccountBasicData(accessToken); data.setAccessToken(accessToken); data.setRefreshToken(refreshToken); return data; diff --git a/wise-api/src/main/java/com/wisemapping/webmvc/MvcLoginController.java b/wise-api/src/main/java/com/wisemapping/webmvc/MvcLoginController.java deleted file mode 100644 index 6f12760d..00000000 --- a/wise-api/src/main/java/com/wisemapping/webmvc/MvcLoginController.java +++ /dev/null @@ -1,46 +0,0 @@ -/* -* Copyright [2022] [wisemapping] -* -* Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the -* "powered by wisemapping" text requirement on every single page; -* you may not use this file except in compliance with the License. -* You may obtain a copy of the license at -* -* http://www.wisemapping.org/license -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.wisemapping.webmvc; - -import com.wisemapping.model.User; -import com.wisemapping.security.Utils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -@Controller -@PreAuthorize("permitAll()") -public class MvcLoginController { - - - @RequestMapping(value = "c/login", method = RequestMethod.GET) - protected ModelAndView showLoginPage() { - final User user = Utils.getUser(false); - ModelAndView result; - if (user != null) { - result = new ModelAndView("forward:/c/maps/"); - } else { - result = new ModelAndView("reactInclude"); - } - return result; - } -} diff --git a/wise-api/src/main/resources/application.yml b/wise-api/src/main/resources/application.yml index 38d3c5c5..ad13ef60 100644 --- a/wise-api/src/main/resources/application.yml +++ b/wise-api/src/main/resources/application.yml @@ -60,15 +60,28 @@ app: mail: serverSendEmail: root@localhost supportEmail: root@localhost + + ####################################################################################### + # Google OAuth Authentication + ####################################################################################### + # OAuth Client id + #security.oauth2.google.clientId= + # OAuth Client secret + #security.oauth2.google.clientSecret= + # Redirect to this url, this url must be configured in the google app {baseurl}/c/registration-google + #security.oauth2.google.callbackUrl= + security: + oauth2: + google: + confirmUrl: https://oauth2.googleapis.com/token + userinfoUrl: https://www:googleapis.com/oauth2/v3/userinfo + url: https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=${app.security.oauth2.google.callbackUrl}&prompt=consent&response_type=code&client_id=${app.security.oauth2.google.clientId}&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&access_type=offline&state=wisemapping&include_granted_scopes=true + # accounts: # exclusion: # domain: - - - - google: ads: enabled: false @@ -79,12 +92,6 @@ google: enabled: true secretKey: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe siteKey: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI -security: - oauth2: - google: - confirmUrl: https://oauth2.googleapis.com/token - url: https//review - userinfoUrl: https://www.googleapis.com/oauth2/v3/userinfo site: homepage: c/login static: From b13748d47d5b81ad8b5c6f506d028701d15a8e79 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Fri, 16 Feb 2024 22:17:38 -0800 Subject: [PATCH 072/110] Remove UI support --- .../service/NotificationService.java | 10 +- .../wisemapping/view/ChangePasswordBean.java | 41 ----- .../webmvc/ApplicationContextInitializer.java | 42 ----- .../webmvc/MvcMindmapController.java | 167 ------------------ .../webmvc/MvcUsersController.java | 68 ------- wise-api/src/main/resources/application.yml | 2 +- wise-api/src/main/resources/public/ads.txt | 1 - wise-api/src/main/resources/public/robots.txt | 9 - wise-api/src/main/webapp/WEB-INF/jsp/init.jsp | 7 - .../main/webapp/WEB-INF/jsp/mindmapEditor.jsp | 53 ------ .../webapp/WEB-INF/jsp/mindmapViewonly.jsp | 120 ------------- .../main/webapp/WEB-INF/jsp/pageHeaders.jsf | 24 --- .../main/webapp/WEB-INF/jsp/reactInclude.jsp | 60 ------- 13 files changed, 3 insertions(+), 601 deletions(-) delete mode 100644 wise-api/src/main/java/com/wisemapping/view/ChangePasswordBean.java delete mode 100644 wise-api/src/main/java/com/wisemapping/webmvc/ApplicationContextInitializer.java delete mode 100644 wise-api/src/main/java/com/wisemapping/webmvc/MvcMindmapController.java delete mode 100644 wise-api/src/main/java/com/wisemapping/webmvc/MvcUsersController.java delete mode 100644 wise-api/src/main/resources/public/ads.txt delete mode 100644 wise-api/src/main/resources/public/robots.txt delete mode 100644 wise-api/src/main/webapp/WEB-INF/jsp/init.jsp delete mode 100644 wise-api/src/main/webapp/WEB-INF/jsp/mindmapEditor.jsp delete mode 100644 wise-api/src/main/webapp/WEB-INF/jsp/mindmapViewonly.jsp delete mode 100644 wise-api/src/main/webapp/WEB-INF/jsp/pageHeaders.jsf delete mode 100644 wise-api/src/main/webapp/WEB-INF/jsp/reactInclude.jsp diff --git a/wise-api/src/main/java/com/wisemapping/service/NotificationService.java b/wise-api/src/main/java/com/wisemapping/service/NotificationService.java index 4534df18..ccb52c71 100644 --- a/wise-api/src/main/java/com/wisemapping/service/NotificationService.java +++ b/wise-api/src/main/java/com/wisemapping/service/NotificationService.java @@ -86,7 +86,7 @@ final public class NotificationService { mailerService.sendEmail(formMail, collabEmail, subject, model, "newCollaboration.vm"); } catch (Exception e) { - handleException(e); + logger.info(e.getMessage(), e); } } @@ -141,16 +141,10 @@ final public class NotificationService { logger.debug("Email properties->" + model); mailerService.sendEmail(mailerService.getServerSenderEmail(), user.getEmail(), mailSubject, model, "baseLayout.vm"); } catch (Exception e) { - handleException(e); + logger.info(e.getMessage(), e); } } - private void handleException(Exception e) { - System.err.println("An expected error has occurred trying to send an email notification. Usually, the main reason for this is that the SMTP server properties has not been configured properly. Edit the WEB-INF/app.properties file and verify the SMTP server configuration properties."); - System.err.println("Cause:" + e.getMessage()); - - } - public void setMailer(MailerService mailerService) { this.mailerService = mailerService; } diff --git a/wise-api/src/main/java/com/wisemapping/view/ChangePasswordBean.java b/wise-api/src/main/java/com/wisemapping/view/ChangePasswordBean.java deleted file mode 100644 index eeec894c..00000000 --- a/wise-api/src/main/java/com/wisemapping/view/ChangePasswordBean.java +++ /dev/null @@ -1,41 +0,0 @@ -/* -* Copyright [2022] [wisemapping] -* -* Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the -* "powered by wisemapping" text requirement on every single page; -* you may not use this file except in compliance with the License. -* You may obtain a copy of the license at -* -* http://www.wisemapping.org/license -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.wisemapping.view; - -public class ChangePasswordBean { - - private String password; - private String retryPassword; - - public String getPassword() { - return password; - } - - public void setPassword(String e) { - this.password = e; - } - - public String getRetryPassword() { - return retryPassword; - } - - public void setRetryPassword(String e) { - this.retryPassword = e; - } -} \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/webmvc/ApplicationContextInitializer.java b/wise-api/src/main/java/com/wisemapping/webmvc/ApplicationContextInitializer.java deleted file mode 100644 index d011e92c..00000000 --- a/wise-api/src/main/java/com/wisemapping/webmvc/ApplicationContextInitializer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* -* Copyright [2022] [wisemapping] -* -* Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the -* "powered by wisemapping" text requirement on every single page; -* you may not use this file except in compliance with the License. -* You may obtain a copy of the license at -* -* http://www.wisemapping.org/license -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package com.wisemapping.webmvc; - - -import org.jetbrains.annotations.NotNull; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.ResourcePropertySource; -import org.springframework.web.context.ConfigurableWebApplicationContext; -import org.springframework.web.context.support.ServletContextResource; - -import java.io.IOException; -import java.util.Objects; - -public class ApplicationContextInitializer implements org.springframework.context.ApplicationContextInitializer { - - public void initialize(@NotNull ConfigurableWebApplicationContext ctx) { - try { - final Resource resource = new ServletContextResource(Objects.requireNonNull(ctx.getServletContext()), "/WEB-INF/app.properties"); - final ResourcePropertySource resourcePropertySource = new ResourcePropertySource(resource); - ctx.getEnvironment().getPropertySources().addFirst(resourcePropertySource); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - -} \ No newline at end of file diff --git a/wise-api/src/main/java/com/wisemapping/webmvc/MvcMindmapController.java b/wise-api/src/main/java/com/wisemapping/webmvc/MvcMindmapController.java deleted file mode 100644 index 57294ec3..00000000 --- a/wise-api/src/main/java/com/wisemapping/webmvc/MvcMindmapController.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright [2022] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.wisemapping.webmvc; - - -import com.wisemapping.exceptions.AccessDeniedSecurityException; -import com.wisemapping.exceptions.MapCouldNotFoundException; -import com.wisemapping.exceptions.MapNotPublicSecurityException; -import com.wisemapping.exceptions.WiseMappingException; -import com.wisemapping.model.CollaborationRole; -import com.wisemapping.model.Mindmap; -import com.wisemapping.model.User; -import com.wisemapping.security.Utils; -import com.wisemapping.service.LockManager; -import com.wisemapping.service.MindmapService; -import com.wisemapping.view.MindMapBean; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.ModelAndView; - -import java.util.Locale; - -@Controller -@Transactional(propagation = Propagation.REQUIRED) -public class MvcMindmapController { - - @Qualifier("mindmapService") - @Autowired - private MindmapService mindmapService; - - @RequestMapping(value = "c/maps/{id}/print") - public String showPrintPage(@PathVariable int id, @NotNull Model model) throws MapCouldNotFoundException, AccessDeniedSecurityException { - - final MindMapBean mindmap = findMindmapBean(id); - model.addAttribute("principal", Utils.getUser()); - model.addAttribute("mindmap", mindmap); - model.addAttribute("creatorFullName", mindmap.getCreator().getFullName()); - final Locale locale = LocaleContextHolder.getLocale(); - model.addAttribute("locale", locale.toString().toLowerCase()); - return "mindmapViewonly"; - } - - @RequestMapping(value = "c/maps/") - public String showListPage(@NotNull Model model) { - return "reactInclude"; - } - - @RequestMapping(value = "c/maps/{id}/edit", method = RequestMethod.GET) - public String showMindmapEditorPage(@PathVariable int id, @NotNull Model model) throws WiseMappingException { - return showEditorPage(id, model, true); - } - - private String showEditorPage(int id, @NotNull final Model model, boolean requiresLock) throws WiseMappingException { - final MindMapBean mindmapBean = findMindmapBean(id); - final Mindmap mindmap = mindmapBean.getDelegated(); - final User user = Utils.getUser(); - final Locale locale = LocaleContextHolder.getLocale(); - - // Is the mindmap locked ?. - boolean isLocked = false; - boolean readOnlyMode = !requiresLock || !mindmap.hasPermissions(user, CollaborationRole.EDITOR); - if (!readOnlyMode) { - final LockManager lockManager = this.mindmapService.getLockManager(); - if (lockManager.isLocked(mindmap) && !lockManager.isLockedBy(mindmap, user)) { - isLocked = true; - } - model.addAttribute("lockInfo", lockManager.getLockInfo(mindmap)); - } - // Set render attributes ... - model.addAttribute("mindmap", mindmapBean); - - // Configure default locale for the editor ... - model.addAttribute("locale", locale.toString().toLowerCase()); - model.addAttribute("principal", user); - model.addAttribute("mindmapLocked", isLocked); - - return "mindmapEditor"; - } - - @RequestMapping(value = "c/maps/{id}/view", method = RequestMethod.GET) - public String showMindmapViewerPage(@PathVariable int id, @NotNull Model model) throws WiseMappingException { - final String result = showPrintPage(id, model); - return result; - } - - @RequestMapping(value = "c/maps/{id}/try", method = RequestMethod.GET) - @PreAuthorize("permitAll()") - public String showMindmapTryPage(@PathVariable int id, @NotNull Model model) throws WiseMappingException { - return showEditorPage(id, model, false); - } - - @RequestMapping(value = "c/maps/{id}/{hid}/view", method = RequestMethod.GET) - public String showMindmapViewerRevPage(@PathVariable int id, @PathVariable int hid, @NotNull Model model) throws WiseMappingException { - final String result = showPrintPage(id, model); - model.addAttribute("hid", String.valueOf(hid)); - return result; - } - - @RequestMapping(value = "c/maps/{id}/embed") - @PreAuthorize("permitAll()") - public ModelAndView showEmbeddedPage(@PathVariable int id, @RequestParam(required = false) Float zoom) throws MapCouldNotFoundException, MapNotPublicSecurityException, AccessDeniedSecurityException { - if (!mindmapService.isMindmapPublic(id)) { - throw new MapNotPublicSecurityException("Map " + id + " is not public."); - } - - final MindMapBean mindmap = findMindmapBean(id); - final ModelAndView view = new ModelAndView("mindmapViewonly", "mindmap", mindmap); - view.addObject("zoom", zoom == null ? 1 : zoom); - final Locale locale = LocaleContextHolder.getLocale(); - view.addObject("locale", locale.toString().toLowerCase()); - return view; - } - - @RequestMapping(value = "c/maps/{id}/public", method = RequestMethod.GET) - @PreAuthorize("permitAll()") - public String showPublicViewPage(@PathVariable int id, @NotNull Model model) throws WiseMappingException { - if (!mindmapService.isMindmapPublic(id)) { - throw new MapNotPublicSecurityException("Map " + id + " is not public."); - } - return this.showPrintPage(id, model); - } - - @NotNull - private Mindmap findMindmap(int mapId) throws MapCouldNotFoundException { - final Mindmap result = mindmapService.findMindmapById(mapId); - if (result == null) { - throw new MapCouldNotFoundException("Map could not be found " + mapId); - } - return result; - - } - - @NotNull - private MindMapBean findMindmapBean(int mapId) throws MapCouldNotFoundException, AccessDeniedSecurityException { - final User user = Utils.getUser(); - if (!mindmapService.hasPermissions(user, mapId, CollaborationRole.VIEWER)) { - throw new AccessDeniedSecurityException(mapId, user); - } - - final Mindmap mindmap = findMindmap(mapId); - return new MindMapBean(mindmap, Utils.getUser()); - } -} diff --git a/wise-api/src/main/java/com/wisemapping/webmvc/MvcUsersController.java b/wise-api/src/main/java/com/wisemapping/webmvc/MvcUsersController.java deleted file mode 100644 index d626c20d..00000000 --- a/wise-api/src/main/java/com/wisemapping/webmvc/MvcUsersController.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright [2022] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.wisemapping.webmvc; - - -import com.wisemapping.service.UserService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.ModelAndView; - -@Controller -public class MvcUsersController { - - @Qualifier("userService") - @Autowired - private UserService userService; - - @RequestMapping(value = "c/forgot-password", method = RequestMethod.GET) - @PreAuthorize("permitAll()") - public ModelAndView showResetPasswordPage() { - return new ModelAndView("reactInclude"); - } - - @RequestMapping(value = "c/registration-google", method = RequestMethod.GET) - @PreAuthorize("permitAll()") - public ModelAndView processGoogleCallback() { - return new ModelAndView("reactInclude"); - } - - @RequestMapping(value = "c/registration", method = RequestMethod.GET) - @PreAuthorize("permitAll()") - public ModelAndView showRegistrationPage() { - return new ModelAndView("reactInclude"); - } - - @RequestMapping(value = "c/registration-success", method = RequestMethod.GET) - @PreAuthorize("permitAll()") - public ModelAndView showRegistrationSuccess() { - return new ModelAndView("reactInclude"); - } - - @RequestMapping(value = "c/forgot-password-success", method = RequestMethod.GET) - @PreAuthorize("permitAll()") - public ModelAndView showResetPasswordSuccess() { - return new ModelAndView("reactInclude"); - } -} - diff --git a/wise-api/src/main/resources/application.yml b/wise-api/src/main/resources/application.yml index ad13ef60..29b196ae 100644 --- a/wise-api/src/main/resources/application.yml +++ b/wise-api/src/main/resources/application.yml @@ -46,7 +46,7 @@ logging: org: apache: tomcat: INFO - root: TRACE + root: INFO # Application Configuration. app: diff --git a/wise-api/src/main/resources/public/ads.txt b/wise-api/src/main/resources/public/ads.txt deleted file mode 100644 index 63aef506..00000000 --- a/wise-api/src/main/resources/public/ads.txt +++ /dev/null @@ -1 +0,0 @@ -google.com, pub-4996113942657337, DIRECT, f08c47fec0942fa0 \ No newline at end of file diff --git a/wise-api/src/main/resources/public/robots.txt b/wise-api/src/main/resources/public/robots.txt deleted file mode 100644 index dd283132..00000000 --- a/wise-api/src/main/resources/public/robots.txt +++ /dev/null @@ -1,9 +0,0 @@ -Sitemap: https://www.wisemapping.com/sitemap.xml - -User-agent: * -Allow: / -Disallow: /c/restful/maps/*/document/xml-pub -Disallow: /c/maps/*/edit -Disallow: /c/maps/*/public -Disallow: /c/maps/*/try - diff --git a/wise-api/src/main/webapp/WEB-INF/jsp/init.jsp b/wise-api/src/main/webapp/WEB-INF/jsp/init.jsp deleted file mode 100644 index 94a2f9ba..00000000 --- a/wise-api/src/main/webapp/WEB-INF/jsp/init.jsp +++ /dev/null @@ -1,7 +0,0 @@ -<%@taglib uri="jakarta.tags.functions" prefix="fn" %> -<%@taglib uri="jakarta.tags.core" prefix="c"%> -<% - - request.setAttribute("principal", com.wisemapping.security.Utils.getUser()); -%> - diff --git a/wise-api/src/main/webapp/WEB-INF/jsp/mindmapEditor.jsp b/wise-api/src/main/webapp/WEB-INF/jsp/mindmapEditor.jsp deleted file mode 100644 index 2bc66a0b..00000000 --- a/wise-api/src/main/webapp/WEB-INF/jsp/mindmapEditor.jsp +++ /dev/null @@ -1,53 +0,0 @@ -<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %> -<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %> -<%@ include file="init.jsp" %> - -<%--@elvariable id="mindmap" type="com.wisemapping.model.Mindmap"--%> -<%--@elvariable id="editorTryMode" type="java.lang.Boolean"--%> -<%--@elvariable id="editorTryMode" type="java.lang.String"--%> -<%--@elvariable id="lockInfo" type="com.wisemapping.service.LockInfo"--%> - - - - - - - - - - - - - <%@ include file="pageHeaders.jsf" %> - - Loading ... | WiseMapping - - - - - - - -
- - - - - diff --git a/wise-api/src/main/webapp/WEB-INF/jsp/mindmapViewonly.jsp b/wise-api/src/main/webapp/WEB-INF/jsp/mindmapViewonly.jsp deleted file mode 100644 index 78210adf..00000000 --- a/wise-api/src/main/webapp/WEB-INF/jsp/mindmapViewonly.jsp +++ /dev/null @@ -1,120 +0,0 @@ -<%@page pageEncoding="UTF-8" %> -<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %> - -<%@include file="init.jsp" %> - - - -<%--@elvariable id="mindmap" type="com.wisemapping.model.Mindmap"--%> - - - - - - - - - - - - - ${mindmap.title} | <spring:message code="SITE.TITLE"/> - <%@ include file="pageHeaders.jsf" %> - - - - - - - - - - - - - -
- -
-
- - - - - -
- :${creatorFullName} - :${mindmap.title} -
- - - -
-
- - -
- -
-
-
- - - - diff --git a/wise-api/src/main/webapp/WEB-INF/jsp/pageHeaders.jsf b/wise-api/src/main/webapp/WEB-INF/jsp/pageHeaders.jsf deleted file mode 100644 index d4f1f025..00000000 --- a/wise-api/src/main/webapp/WEB-INF/jsp/pageHeaders.jsf +++ /dev/null @@ -1,24 +0,0 @@ -<%@taglib uri="jakarta.tags.core" prefix="c"%> -<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/wise-api/src/main/webapp/WEB-INF/jsp/reactInclude.jsp b/wise-api/src/main/webapp/WEB-INF/jsp/reactInclude.jsp deleted file mode 100644 index 272f2c2d..00000000 --- a/wise-api/src/main/webapp/WEB-INF/jsp/reactInclude.jsp +++ /dev/null @@ -1,60 +0,0 @@ -<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %> -<%@taglib uri="jakarta.tags.functions" prefix="fn" %> -<%@taglib uri="jakarta.tags.core" prefix="c"%> - - - - - - - - - - - - <%@ include file="pageHeaders.jsf" %> - - - - - <%-- Google Ads Sense Config. Lazy loading optimization --%> - - - - - - -
- - - - - - From 83e080d67709cb27051c9708da0facd9060b1d50 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Fri, 16 Feb 2024 22:49:33 -0800 Subject: [PATCH 073/110] Update to MySQL 8. --- config/database/mysql/create-database.sql | 13 ++- config/database/mysql/create-schemas.sql | 128 +++++++++++++++++++++- 2 files changed, 139 insertions(+), 2 deletions(-) diff --git a/config/database/mysql/create-database.sql b/config/database/mysql/create-database.sql index edadeef9..940c5af7 100644 --- a/config/database/mysql/create-database.sql +++ b/config/database/mysql/create-database.sql @@ -1 +1,12 @@ -# # Command: mysql -u root -p < create_database.sql # DROP DATABASE IF EXISTS wisemapping; CREATE DATABASE IF NOT EXISTS wisemapping CHARACTER SET = 'utf8' COLLATE = 'utf8_unicode_ci'; GRANT ALL ON wisemapping.* TO 'wisemapping'@'localhost'; SET PASSWORD FOR 'wisemapping'@'localhost' = PASSWORD('password'); \ No newline at end of file +# +# Command: mysql -u root -p < create-database.sql +# +DROP DATABASE IF EXISTS wisemapping; + +CREATE DATABASE IF NOT EXISTS wisemapping + CHARACTER SET = 'utf8' + COLLATE = 'utf8_unicode_ci'; + +CREATE USER 'wisemapping'@'%' IDENTIFIED BY 'password'; +GRANT ALL PRIVILEGES ON wisemapping.* TO 'wisemapping'@'%' WITH GRANT OPTION; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/config/database/mysql/create-schemas.sql b/config/database/mysql/create-schemas.sql index b11e0754..32f04c9c 100644 --- a/config/database/mysql/create-schemas.sql +++ b/config/database/mysql/create-schemas.sql @@ -1 +1,127 @@ -# # Command: mysql -u root -p < create_schemas.sql # USE wisemapping; CREATE TABLE COLLABORATOR ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, email VARCHAR(255) CHARACTER SET utf8 NOT NULL UNIQUE, creation_date DATE ) CHARACTER SET utf8; CREATE TABLE USER ( colaborator_id INTEGER NOT NULL PRIMARY KEY, authentication_type CHAR(1) CHARACTER SET utf8 NOT NULL, authenticator_uri VARCHAR(255) CHARACTER SET utf8, firstname VARCHAR(255) CHARACTER SET utf8 NOT NULL, lastname VARCHAR(255) CHARACTER SET utf8 NOT NULL, password VARCHAR(255) CHARACTER SET utf8 NOT NULL, activation_code BIGINT(20) NOT NULL, activation_date DATE, allow_send_email CHAR(1) CHARACTER SET utf8 NOT NULL DEFAULT 0, locale VARCHAR(5), google_sync BOOL, sync_code VARCHAR(255), google_token VARCHAR(255), FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id) ON DELETE CASCADE ON UPDATE NO ACTION ) CHARACTER SET utf8; CREATE TABLE MINDMAP ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, title VARCHAR(255) CHARACTER SET utf8 NOT NULL, description VARCHAR(255) CHARACTER SET utf8 NOT NULL, xml MEDIUMBLOB NOT NULL, public BOOL NOT NULL DEFAULT 0, creation_date DATETIME, edition_date DATETIME, creator_id INTEGER NOT NULL, last_editor_id INTEGER NOT NULL, FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id) ON DELETE CASCADE ON UPDATE NO ACTION ) CHARACTER SET utf8; CREATE TABLE LABEL ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, title VARCHAR(30) CHARACTER SET utf8 NOT NULL, creator_id INTEGER NOT NULL, parent_label_id INTEGER, color VARCHAR(7) NOT NULL, FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id), FOREIGN KEY (parent_label_id) REFERENCES LABEL (id) ON DELETE CASCADE ON UPDATE NO ACTION ) CHARACTER SET utf8; CREATE TABLE R_LABEL_MINDMAP ( mindmap_id INTEGER NOT NULL, label_id INTEGER NOT NULL, PRIMARY KEY (mindmap_id, label_id), FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id), FOREIGN KEY (label_id) REFERENCES LABEL (id) ON DELETE CASCADE ON UPDATE NO ACTION ) CHARACTER SET utf8; CREATE TABLE MINDMAP_HISTORY (id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, xml MEDIUMBLOB NOT NULL, mindmap_id INTEGER NOT NULL, creation_date DATETIME, editor_id INTEGER NOT NULL, FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id) ON DELETE CASCADE ON UPDATE NO ACTION ) CHARACTER SET utf8; CREATE TABLE COLLABORATION_PROPERTIES ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, starred BOOL NOT NULL DEFAULT 0, mindmap_properties VARCHAR(512) CHARACTER SET utf8 ) CHARACTER SET utf8; CREATE TABLE COLLABORATION ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, colaborator_id INTEGER NOT NULL, properties_id INTEGER NOT NULL, mindmap_id INTEGER NOT NULL, role_id INTEGER NOT NULL, UNIQUE KEY UC_ROLE (mindmap_id,colaborator_id), FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id), FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id) ON DELETE CASCADE ON UPDATE NO ACTION, FOREIGN KEY (properties_id) REFERENCES COLLABORATION_PROPERTIES (id) ON DELETE CASCADE ON UPDATE NO ACTION ) CHARACTER SET utf8; CREATE TABLE ACCESS_AUDITORY ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, login_date DATE, user_id INTEGER NOT NULL, FOREIGN KEY (user_id) REFERENCES USER (colaborator_id) ON DELETE CASCADE ON UPDATE NO ACTION ) CHARACTER SET utf8; COMMIT; \ No newline at end of file +# +# Command: mysql -u root -p < create-schemas.sql +# + +USE wisemapping; + +CREATE TABLE COLLABORATOR ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + email VARCHAR(255) + CHARACTER SET utf8 NOT NULL UNIQUE, + creation_date DATE +) + CHARACTER SET utf8; + +CREATE TABLE USER ( + colaborator_id INTEGER NOT NULL PRIMARY KEY, + authentication_type CHAR(1) + CHARACTER SET utf8 NOT NULL, + authenticator_uri VARCHAR(255) + CHARACTER SET utf8, + firstname VARCHAR(255) CHARACTER SET utf8 NOT NULL, + lastname VARCHAR(255) CHARACTER SET utf8 NOT NULL, + password VARCHAR(255) CHARACTER SET utf8 NOT NULL, + activation_code BIGINT(20) NOT NULL, + activation_date DATE, + allow_send_email CHAR(1) CHARACTER SET utf8 NOT NULL DEFAULT 0, + locale VARCHAR(5), + google_sync BOOL, + sync_code VARCHAR(255), + google_token VARCHAR(255), + FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id) + ON DELETE CASCADE + ON UPDATE NO ACTION +) + CHARACTER SET utf8; + +CREATE TABLE MINDMAP ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + title VARCHAR(255) + CHARACTER SET utf8 NOT NULL, + description VARCHAR(255) + CHARACTER SET utf8 NOT NULL, + xml MEDIUMBLOB NOT NULL, + public BOOL NOT NULL DEFAULT 0, + creation_date DATETIME, + edition_date DATETIME, + creator_id INTEGER NOT NULL, + last_editor_id INTEGER NOT NULL, + FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id) + ON DELETE CASCADE + ON UPDATE NO ACTION +) + CHARACTER SET utf8; + +CREATE TABLE LABEL ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + title VARCHAR(30) + CHARACTER SET utf8 NOT NULL, + creator_id INTEGER NOT NULL, + parent_label_id INTEGER, + color VARCHAR(7) NOT NULL, + FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id), + FOREIGN KEY (parent_label_id) REFERENCES LABEL (id) + ON DELETE CASCADE + ON UPDATE NO ACTION +) + CHARACTER SET utf8; + +CREATE TABLE R_LABEL_MINDMAP ( + mindmap_id INTEGER NOT NULL, + label_id INTEGER NOT NULL, + PRIMARY KEY (mindmap_id, label_id), + FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id), + FOREIGN KEY (label_id) REFERENCES LABEL (id) + ON DELETE CASCADE + ON UPDATE NO ACTION +) + CHARACTER SET utf8; + +CREATE TABLE MINDMAP_HISTORY +(id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + xml MEDIUMBLOB NOT NULL, + mindmap_id INTEGER NOT NULL, + creation_date DATETIME, + editor_id INTEGER NOT NULL, + FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id) + ON DELETE CASCADE + ON UPDATE NO ACTION +) + CHARACTER SET utf8; + +CREATE TABLE COLLABORATION_PROPERTIES ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + starred BOOL NOT NULL DEFAULT 0, + mindmap_properties VARCHAR(512) + CHARACTER SET utf8 +) + CHARACTER SET utf8; + +CREATE TABLE COLLABORATION ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + colaborator_id INTEGER NOT NULL, + properties_id INTEGER NOT NULL, + mindmap_id INTEGER NOT NULL, + role_id INTEGER NOT NULL, + UNIQUE KEY UC_ROLE (mindmap_id,colaborator_id), + FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id), + FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id) + ON DELETE CASCADE + ON UPDATE NO ACTION, + FOREIGN KEY (properties_id) REFERENCES COLLABORATION_PROPERTIES (id) + ON DELETE CASCADE + ON UPDATE NO ACTION +) + CHARACTER SET utf8; + +CREATE TABLE ACCESS_AUDITORY ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + login_date DATE, + user_id INTEGER NOT NULL, + FOREIGN KEY (user_id) REFERENCES USER (colaborator_id) + ON DELETE CASCADE + ON UPDATE NO ACTION +) + CHARACTER SET utf8; + +COMMIT; \ No newline at end of file From aadb88451bfa3953a9a083701ac6aea39eaae0e9 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sat, 17 Feb 2024 00:14:09 -0800 Subject: [PATCH 074/110] Mysql --- config/database/mysql/apopulate-schemas.sql | 1 - config/database/mysql/app-mysql.yaml | 14 ++++ config/database/mysql/drop-schemas.sql | 1 - config/database/postgres/create-database.sql | 5 +- config/database/postgres/drop-schemas.sql | 10 --- wise-api/doc/Compile.md | 4 -- wise-api/docker/compose.yaml | 9 --- wise-api/src/main/resources/data-mysql.sql | 1 + .../src/main/resources/data-postgresql.sql | 8 +-- .../src/main/resources/schema-mysql.sql | 66 ++++++++----------- 10 files changed, 48 insertions(+), 71 deletions(-) delete mode 100644 config/database/mysql/apopulate-schemas.sql create mode 100644 config/database/mysql/app-mysql.yaml delete mode 100644 config/database/mysql/drop-schemas.sql delete mode 100644 config/database/postgres/drop-schemas.sql delete mode 100644 wise-api/doc/Compile.md delete mode 100644 wise-api/docker/compose.yaml create mode 100644 wise-api/src/main/resources/data-mysql.sql rename config/database/postgres/create-schemas.sql => wise-api/src/main/resources/data-postgresql.sql (92%) rename config/database/mysql/create-schemas.sql => wise-api/src/main/resources/schema-mysql.sql (68%) diff --git a/config/database/mysql/apopulate-schemas.sql b/config/database/mysql/apopulate-schemas.sql deleted file mode 100644 index f5e38020..00000000 --- a/config/database/mysql/apopulate-schemas.sql +++ /dev/null @@ -1 +0,0 @@ -# # Command: mysql -u root -p < apopulate_schemas.sql # INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (1, 'test@wisemapping.org', CURRENT_DATE()); INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) VALUES (1, 'Test', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D'); INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (2, 'admin@wisemapping.org', CURRENT_DATE()); INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) VALUES (2, 'Admin', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D'); COMMIT; \ No newline at end of file diff --git a/config/database/mysql/app-mysql.yaml b/config/database/mysql/app-mysql.yaml new file mode 100644 index 00000000..be89a7db --- /dev/null +++ b/config/database/mysql/app-mysql.yaml @@ -0,0 +1,14 @@ + +spring: + datasource: + url: jdbc:mysql://localhost:3306/wisemapping?useUnicode=yes&characterEncoding=UTF-8 + driver-class-name: com.mysql.cj.jdbc.Driver + password: password + username: wisemapping + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.MySQLDialect + sql: + init: + platform: mysql \ No newline at end of file diff --git a/config/database/mysql/drop-schemas.sql b/config/database/mysql/drop-schemas.sql deleted file mode 100644 index 6be70e14..00000000 --- a/config/database/mysql/drop-schemas.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE IF EXISTS ACCESS_AUDITORY; DROP TABLE IF EXISTS COLLABORATION; DROP TABLE IF EXISTS COLLABORATION_PROPERTIES; DROP TABLE IF EXISTS MINDMAP_HISTORY; DROP TABLE IF EXISTS LABEL; DROP TABLE IF EXISTS MINDMAP; DROP TABLE IF EXISTS R_LABEL_MINDMAP DROP TABLE IF EXISTS USER; DROP TABLE IF EXISTS COLLABORATOR; COMMIT; \ No newline at end of file diff --git a/config/database/postgres/create-database.sql b/config/database/postgres/create-database.sql index 3a1305f2..8d231264 100644 --- a/config/database/postgres/create-database.sql +++ b/config/database/postgres/create-database.sql @@ -1,4 +1,7 @@ + CREATE DATABASE wisemapping; CREATE USER wisemapping WITH PASSWORD 'password'; +GRANT ALL PRIVILEGES ON DATABASE wisemapping TO wisemapping; -GRANT ALL PRIVILEGES ON DATABASE wisemapping TO wisemapping; \ No newline at end of file +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO wisemapping; +GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO wisemapping; diff --git a/config/database/postgres/drop-schemas.sql b/config/database/postgres/drop-schemas.sql deleted file mode 100644 index 6b49abbe..00000000 --- a/config/database/postgres/drop-schemas.sql +++ /dev/null @@ -1,10 +0,0 @@ -DROP TABLE IF EXISTS ACCESS_AUDITORY; -DROP TABLE IF EXISTS COLLABORATION; -DROP TABLE IF EXISTS COLLABORATION_PROPERTIES; -DROP TABLE IF EXISTS MINDMAP_HISTORY; -DROP TABLE IF EXISTS R_LABEL_MINDMAP; -DROP TABLE IF EXISTS "LABEL"; -DROP TABLE IF EXISTS MINDMAP; -DROP TABLE IF EXISTS "USER"; -DROP TABLE IF EXISTS COLLABORATOR; -COMMIT; \ No newline at end of file diff --git a/wise-api/doc/Compile.md b/wise-api/doc/Compile.md deleted file mode 100644 index d0727845..00000000 --- a/wise-api/doc/Compile.md +++ /dev/null @@ -1,4 +0,0 @@ -# Compilation and Execution - -Your will find all the steps and required documentation here: http://www.wisemapping.org/downloads/source - diff --git a/wise-api/docker/compose.yaml b/wise-api/docker/compose.yaml deleted file mode 100644 index cea52055..00000000 --- a/wise-api/docker/compose.yaml +++ /dev/null @@ -1,9 +0,0 @@ -services: - database: - image: 'postgres:15.2' - ports: - - '5432' - environment: - - 'POSTGRES_USER=myuser' - - 'POSTGRES_DB=mydatabase' - - 'POSTGRES_PASSWORD=secret' \ No newline at end of file diff --git a/wise-api/src/main/resources/data-mysql.sql b/wise-api/src/main/resources/data-mysql.sql new file mode 100644 index 00000000..3ccef8a2 --- /dev/null +++ b/wise-api/src/main/resources/data-mysql.sql @@ -0,0 +1 @@ +INSERT IGNORE INTO COLLABORATOR (id, email, creation_date) VALUES (1, 'test@wisemapping.org', CURRENT_DATE()); INSERT IGNORE INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) VALUES (1, 'Test', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D'); INSERT IGNORE INTO COLLABORATOR (id, email, creation_date) VALUES (2, 'admin@wisemapping.org', CURRENT_DATE()); INSERT IGNORE INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type) VALUES (2, 'Admin', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D'); \ No newline at end of file diff --git a/config/database/postgres/create-schemas.sql b/wise-api/src/main/resources/data-postgresql.sql similarity index 92% rename from config/database/postgres/create-schemas.sql rename to wise-api/src/main/resources/data-postgresql.sql index cbb930cd..88225b5b 100644 --- a/config/database/postgres/create-schemas.sql +++ b/wise-api/src/main/resources/data-postgresql.sql @@ -83,10 +83,4 @@ CREATE TABLE ACCESS_AUDITORY ( login_date DATE, user_id INTEGER NOT NULL, FOREIGN KEY (user_id) REFERENCES "USER" (colaborator_id) ON DELETE CASCADE ON UPDATE NO ACTION -); - - -GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO wisemapping; -GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO wisemapping; - -COMMIT; +); \ No newline at end of file diff --git a/config/database/mysql/create-schemas.sql b/wise-api/src/main/resources/schema-mysql.sql similarity index 68% rename from config/database/mysql/create-schemas.sql rename to wise-api/src/main/resources/schema-mysql.sql index 32f04c9c..27735a69 100644 --- a/config/database/mysql/create-schemas.sql +++ b/wise-api/src/main/resources/schema-mysql.sql @@ -1,29 +1,22 @@ -# -# Command: mysql -u root -p < create-schemas.sql -# - -USE wisemapping; - -CREATE TABLE COLLABORATOR ( - id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - email VARCHAR(255) - CHARACTER SET utf8 NOT NULL UNIQUE, +CREATE TABLE IF NOT EXISTS COLLABORATOR ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + email VARCHAR(255) CHARACTER SET UTF8MB4 NOT NULL UNIQUE, creation_date DATE ) - CHARACTER SET utf8; +CHARACTER SET UTF8MB4; -CREATE TABLE USER ( +CREATE TABLE IF NOT EXISTS USER ( colaborator_id INTEGER NOT NULL PRIMARY KEY, authentication_type CHAR(1) - CHARACTER SET utf8 NOT NULL, + CHARACTER SET UTF8MB4 NOT NULL, authenticator_uri VARCHAR(255) CHARACTER SET utf8, - firstname VARCHAR(255) CHARACTER SET utf8 NOT NULL, - lastname VARCHAR(255) CHARACTER SET utf8 NOT NULL, - password VARCHAR(255) CHARACTER SET utf8 NOT NULL, + firstname VARCHAR(255) CHARACTER SET UTF8MB4 NOT NULL, + lastname VARCHAR(255) CHARACTER SET UTF8MB4 NOT NULL, + password VARCHAR(255) CHARACTER SET UTF8MB4 NOT NULL, activation_code BIGINT(20) NOT NULL, activation_date DATE, - allow_send_email CHAR(1) CHARACTER SET utf8 NOT NULL DEFAULT 0, + allow_send_email CHAR(1) CHARACTER SET UTF8MB4 NOT NULL DEFAULT 0, locale VARCHAR(5), google_sync BOOL, sync_code VARCHAR(255), @@ -31,15 +24,14 @@ CREATE TABLE USER ( FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id) ON DELETE CASCADE ON UPDATE NO ACTION -) - CHARACTER SET utf8; +) CHARACTER SET UTF8MB4; -CREATE TABLE MINDMAP ( +CREATE TABLE IF NOT EXISTS MINDMAP ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, title VARCHAR(255) - CHARACTER SET utf8 NOT NULL, + CHARACTER SET UTF8MB4 NOT NULL, description VARCHAR(255) - CHARACTER SET utf8 NOT NULL, + CHARACTER SET utf8, xml MEDIUMBLOB NOT NULL, public BOOL NOT NULL DEFAULT 0, creation_date DATETIME, @@ -50,12 +42,12 @@ CREATE TABLE MINDMAP ( ON DELETE CASCADE ON UPDATE NO ACTION ) - CHARACTER SET utf8; + CHARACTER SET UTF8MB4; -CREATE TABLE LABEL ( +CREATE TABLE IF NOT EXISTS LABEL ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, title VARCHAR(30) - CHARACTER SET utf8 NOT NULL, + CHARACTER SET UTF8MB4 NOT NULL, creator_id INTEGER NOT NULL, parent_label_id INTEGER, color VARCHAR(7) NOT NULL, @@ -64,9 +56,9 @@ CREATE TABLE LABEL ( ON DELETE CASCADE ON UPDATE NO ACTION ) - CHARACTER SET utf8; + CHARACTER SET UTF8MB4; -CREATE TABLE R_LABEL_MINDMAP ( +CREATE TABLE IF NOT EXISTS R_LABEL_MINDMAP ( mindmap_id INTEGER NOT NULL, label_id INTEGER NOT NULL, PRIMARY KEY (mindmap_id, label_id), @@ -75,9 +67,9 @@ CREATE TABLE R_LABEL_MINDMAP ( ON DELETE CASCADE ON UPDATE NO ACTION ) - CHARACTER SET utf8; + CHARACTER SET UTF8MB4; -CREATE TABLE MINDMAP_HISTORY +CREATE TABLE IF NOT EXISTS MINDMAP_HISTORY (id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, xml MEDIUMBLOB NOT NULL, mindmap_id INTEGER NOT NULL, @@ -87,17 +79,17 @@ CREATE TABLE MINDMAP_HISTORY ON DELETE CASCADE ON UPDATE NO ACTION ) - CHARACTER SET utf8; + CHARACTER SET UTF8MB4; -CREATE TABLE COLLABORATION_PROPERTIES ( +CREATE TABLE IF NOT EXISTS COLLABORATION_PROPERTIES ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, starred BOOL NOT NULL DEFAULT 0, mindmap_properties VARCHAR(512) CHARACTER SET utf8 ) - CHARACTER SET utf8; + CHARACTER SET UTF8MB4; -CREATE TABLE COLLABORATION ( +CREATE TABLE IF NOT EXISTS COLLABORATION ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, colaborator_id INTEGER NOT NULL, properties_id INTEGER NOT NULL, @@ -112,9 +104,9 @@ CREATE TABLE COLLABORATION ( ON DELETE CASCADE ON UPDATE NO ACTION ) - CHARACTER SET utf8; + CHARACTER SET UTF8MB4; -CREATE TABLE ACCESS_AUDITORY ( +CREATE TABLE IF NOT EXISTS ACCESS_AUDITORY ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, login_date DATE, user_id INTEGER NOT NULL, @@ -122,6 +114,4 @@ CREATE TABLE ACCESS_AUDITORY ( ON DELETE CASCADE ON UPDATE NO ACTION ) - CHARACTER SET utf8; - -COMMIT; \ No newline at end of file +CHARACTER SET UTF8MB4; \ No newline at end of file From 0dcdc2c263a5b0f6a4f9d77400b35ef678a4e361 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sat, 17 Feb 2024 00:54:41 -0800 Subject: [PATCH 075/110] Fix posgresql --- config/database/postgresql/app-postgresql.yaml | 14 ++++++++++++++ .../{postgres => postgresql}/create-database.sql | 0 2 files changed, 14 insertions(+) create mode 100644 config/database/postgresql/app-postgresql.yaml rename config/database/{postgres => postgresql}/create-database.sql (100%) diff --git a/config/database/postgresql/app-postgresql.yaml b/config/database/postgresql/app-postgresql.yaml new file mode 100644 index 00000000..5f69c5cd --- /dev/null +++ b/config/database/postgresql/app-postgresql.yaml @@ -0,0 +1,14 @@ + +spring: + datasource: + url: jdbc:postgresql://localhost/wisemapping + driver-class-name: org.postgresql.Driver + password: password + username: wisemapping + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect + sql: + init: + platform: postgresql \ No newline at end of file diff --git a/config/database/postgres/create-database.sql b/config/database/postgresql/create-database.sql similarity index 100% rename from config/database/postgres/create-database.sql rename to config/database/postgresql/create-database.sql From 52fdefb57e29f317606c81d6649aefbfb63c0279 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sat, 17 Feb 2024 11:18:43 -0800 Subject: [PATCH 076/110] Fixed. --- config/database/migration/5.0->6.0.sql | 5 ++ .../config/common/CommonConfig.java | 4 +- .../wisemapping/config/common/JPAConfig.java | 4 +- .../com/wisemapping/dao/LabelManager.java | 16 +++--- .../com/wisemapping/dao/LabelManagerImpl.java | 28 +++++----- .../com/wisemapping/dao/MindmapManager.java | 6 +-- .../wisemapping/dao/MindmapManagerImpl.java | 6 +-- .../java/com/wisemapping/dao/UserManager.java | 18 +++---- .../com/wisemapping/dao/UserManagerImpl.java | 34 ++++++------ .../AccessDeniedSecurityException.java | 1 - .../wisemapping/exceptions/LockException.java | 4 +- .../exceptions/SessionExpiredException.java | 6 +-- .../listener/UnlockOnExpireListener.java | 4 +- .../com/wisemapping/model/AccessAuditory.java | 6 +-- .../model/{User.java => Account.java} | 8 +-- .../com/wisemapping/model/Collaboration.java | 2 +- .../com/wisemapping/model/MindMapHistory.java | 6 +-- .../java/com/wisemapping/model/Mindmap.java | 27 +++++----- .../model/{Label.java => MindmapLabel.java} | 20 +++---- .../wisemapping/rest/AccountController.java | 21 ++++---- .../com/wisemapping/rest/AdminController.java | 12 ++--- .../com/wisemapping/rest/BaseController.java | 4 +- .../com/wisemapping/rest/LabelController.java | 20 +++---- .../wisemapping/rest/MindmapController.java | 52 +++++++++---------- .../com/wisemapping/rest/MindmapFilter.java | 16 +++--- .../wisemapping/rest/OAuth2Controller.java | 4 +- .../com/wisemapping/rest/UserController.java | 8 ++- .../com/wisemapping/rest/model/RestLabel.java | 14 ++--- .../wisemapping/rest/model/RestLabelList.java | 6 +-- .../wisemapping/rest/model/RestLockInfo.java | 4 +- .../wisemapping/rest/model/RestMindmap.java | 9 ++-- .../rest/model/RestMindmapHistory.java | 4 +- .../rest/model/RestMindmapInfo.java | 8 +-- .../com/wisemapping/rest/model/RestUser.java | 10 ++-- .../rest/model/RestUserRegistration.java | 8 ++- .../security/AuthenticationProvider.java | 4 +- .../GoogleAuthenticationProvider.java | 4 +- .../MapAccessPermissionEvaluation.java | 8 +-- .../MapPermissionsSecurityAdvice.java | 6 +-- .../security/ReadSecurityAdvise.java | 6 +-- .../security/UpdateSecurityAdvise.java | 6 +-- .../com/wisemapping/security/UserDetails.java | 8 +-- .../security/UserDetailsService.java | 4 +- .../java/com/wisemapping/security/Utils.java | 9 ++-- .../com/wisemapping/service/LabelService.java | 14 ++--- .../wisemapping/service/LabelServiceImpl.java | 14 ++--- .../com/wisemapping/service/LockInfo.java | 8 +-- .../com/wisemapping/service/LockManager.java | 11 ++-- .../wisemapping/service/LockManagerImpl.java | 12 ++--- .../wisemapping/service/MailerService.java | 25 +++++---- .../wisemapping/service/MindmapService.java | 16 +++--- .../service/MindmapServiceImpl.java | 22 ++++---- .../service/NotificationService.java | 22 ++++---- .../com/wisemapping/service/UserService.java | 22 ++++---- .../wisemapping/service/UserServiceImpl.java | 32 ++++++------ .../wisemapping/validator/LabelValidator.java | 14 ++--- .../validator/MapInfoValidator.java | 4 +- .../wisemapping/view/CollaboratorBean.java | 6 +-- .../com/wisemapping/view/MindMapBean.java | 5 +- .../java/com/wisemapping/view/UserBean.java | 6 +-- wise-api/src/main/resources/application.yml | 2 +- wise-api/src/main/resources/data-hsqldb.sql | 2 +- wise-api/src/main/resources/data-mysql.sql | 2 +- .../src/main/resources/data-postgresql.sql | 14 ++--- wise-api/src/main/resources/ehcache.xml | 4 +- wise-api/src/main/resources/schema-hsqldb.sql | 2 +- wise-api/src/main/resources/schema-mysql.sql | 24 ++++----- .../test/rest/RestUserControllerTest.java | 6 +-- 68 files changed, 373 insertions(+), 376 deletions(-) create mode 100644 config/database/migration/5.0->6.0.sql rename wise-api/src/main/java/com/wisemapping/model/{User.java => Account.java} (97%) rename wise-api/src/main/java/com/wisemapping/model/{Label.java => MindmapLabel.java} (85%) diff --git a/config/database/migration/5.0->6.0.sql b/config/database/migration/5.0->6.0.sql new file mode 100644 index 00000000..585ec37d --- /dev/null +++ b/config/database/migration/5.0->6.0.sql @@ -0,0 +1,5 @@ +RENAME TABLE USER TO ACCOUNT; +RENAME TABLE LABEL TO MINDMAP_LABEL; + +ALTER TABLE COLLABORATION +RENAME COLUMN colaboration_id to collaboration_id diff --git a/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java index 561fce36..d068f10c 100644 --- a/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/common/CommonConfig.java @@ -1,7 +1,7 @@ package com.wisemapping.config.common; import com.wisemapping.dao.LabelManagerImpl; -import com.wisemapping.model.User; +import com.wisemapping.model.Account; import com.wisemapping.security.AuthenticationProvider; import com.wisemapping.security.Utils; import com.wisemapping.service.MindmapServiceImpl; @@ -26,7 +26,7 @@ public class CommonConfig { return new AcceptHeaderLocaleResolver() { @Override public Locale resolveLocale(@NotNull HttpServletRequest request) { - final User user = Utils.getUser(); + final Account user = Utils.getUser(); Locale result; if (user != null && user.getLocale() != null) { String locale = user.getLocale(); diff --git a/wise-api/src/main/java/com/wisemapping/config/common/JPAConfig.java b/wise-api/src/main/java/com/wisemapping/config/common/JPAConfig.java index 9f68abdc..87796cdf 100644 --- a/wise-api/src/main/java/com/wisemapping/config/common/JPAConfig.java +++ b/wise-api/src/main/java/com/wisemapping/config/common/JPAConfig.java @@ -1,7 +1,7 @@ package com.wisemapping.config.common; import com.wisemapping.dao.MindmapManagerImpl; -import com.wisemapping.model.User; +import com.wisemapping.model.Account; import com.wisemapping.service.MindmapServiceImpl; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Configuration; @@ -10,7 +10,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @Configuration @EnableJpaRepositories(basePackageClasses={MindmapServiceImpl.class, MindmapManagerImpl.class}) -@EntityScan(basePackageClasses= User.class) +@EntityScan(basePackageClasses= Account.class) public class JPAConfig { } diff --git a/wise-api/src/main/java/com/wisemapping/dao/LabelManager.java b/wise-api/src/main/java/com/wisemapping/dao/LabelManager.java index 7d0363dc..8a6f1c6d 100644 --- a/wise-api/src/main/java/com/wisemapping/dao/LabelManager.java +++ b/wise-api/src/main/java/com/wisemapping/dao/LabelManager.java @@ -1,7 +1,7 @@ package com.wisemapping.dao; -import com.wisemapping.model.Label; -import com.wisemapping.model.User; +import com.wisemapping.model.MindmapLabel; +import com.wisemapping.model.Account; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -9,18 +9,18 @@ import java.util.List; public interface LabelManager { - void addLabel(@NotNull final Label label); + void addLabel(@NotNull final MindmapLabel label); - void saveLabel(@NotNull final Label label); + void saveLabel(@NotNull final MindmapLabel label); @NotNull - List