diff --git a/build.gradle.kts b/build.gradle.kts
index 53746db..0b775a9 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -37,6 +37,7 @@ dependencies {
 	implementation("com.google.code.gson:gson:2.8.6")
 	implementation("org.projectlombok:lombok:1.18.16")
 	implementation("org.jetbrains.kotlin:kotlin-reflect:1.4.32")
+	implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.3")
 
 	runtimeOnly("mysql:mysql-connector-java")
 	testImplementation("org.springframework.boot:spring-boot-starter-test") {
diff --git a/data/db/install.sql b/data/db/install.sql
index d2d3d4e..f3c5d7a 100644
--- a/data/db/install.sql
+++ b/data/db/install.sql
@@ -1443,6 +1443,109 @@ ENGINE=InnoDB
 ;
 
 
+
+-- Struktúra mentése tábla aitrainer2. customer_training_plan
+CREATE TABLE IF NOT EXISTS `customer_training_plan` (
+  `customer_training_plan_id` int(11) NOT NULL AUTO_INCREMENT,
+  `customer_id` int(11) NOT NULL DEFAULT 0,
+  `training_plan_id` int(11) NOT NULL DEFAULT 0,
+  `date_add` datetime DEFAULT NULL,
+  PRIMARY KEY (`customer_training_plan_id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
+
+-- Tábla adatainak mentése aitrainer2.customer_training_plan: ~0 rows (hozzávetőleg)
+/*!40000 ALTER TABLE `customer_training_plan` DISABLE KEYS */;
+/*!40000 ALTER TABLE `customer_training_plan` ENABLE KEYS */;
+
+-- Struktúra mentése tábla aitrainer2. faq
+CREATE TABLE IF NOT EXISTS `faq` (
+  `faq_id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` char(50) COLLATE utf8_hungarian_ci NOT NULL,
+  `description` text COLLATE utf8_hungarian_ci DEFAULT NULL,
+  PRIMARY KEY (`faq_id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
+
+-- Tábla adatainak mentése aitrainer2.faq: ~1 rows (hozzávetőleg)
+/*!40000 ALTER TABLE `faq` DISABLE KEYS */;
+REPLACE INTO `faq` (`faq_id`, `name`, `description`) VALUES
+	(1, 'What is 1RM?', '<p>1RM</p>');
+/*!40000 ALTER TABLE `faq` ENABLE KEYS */;
+
+-- Struktúra mentése tábla aitrainer2. faq_translation
+CREATE TABLE IF NOT EXISTS `faq_translation` (
+  `translation_id` int(11) NOT NULL AUTO_INCREMENT,
+  `faq_id` int(11) NOT NULL DEFAULT 0,
+  `name_translation` char(50) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '0',
+  `description_translation` text COLLATE utf8_hungarian_ci DEFAULT NULL,
+  `language_code` char(2) COLLATE utf8_hungarian_ci DEFAULT 'en',
+  PRIMARY KEY (`translation_id`) USING BTREE,
+  KEY `faq_id` (`faq_id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
+
+-- Tábla adatainak mentése aitrainer2.faq_translation: ~1 rows (hozzávetőleg)
+/*!40000 ALTER TABLE `faq_translation` DISABLE KEYS */;
+REPLACE INTO `faq_translation` (`translation_id`, `faq_id`, `name_translation`, `description_translation`, `language_code`) VALUES
+	(1, 1, '<p>Mi az 1RM</p>', '<p>1RM</p>', 'hu');
+/*!40000 ALTER TABLE `faq_translation` ENABLE KEYS */;
+
+-- Struktúra mentése tábla aitrainer2. training_plan
+CREATE TABLE IF NOT EXISTS `training_plan` (
+  `training_plan_id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` char(50) COLLATE utf8_hungarian_ci NOT NULL,
+  `description` text COLLATE utf8_hungarian_ci DEFAULT NULL,
+  `type` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
+  PRIMARY KEY (`training_plan_id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
+
+-- Tábla adatainak mentése aitrainer2.training_plan: ~2 rows (hozzávetőleg)
+/*!40000 ALTER TABLE `training_plan` DISABLE KEYS */;
+REPLACE INTO `training_plan` (`training_plan_id`, `name`, `description`, `type`) VALUES
+	(1, 'Chest', '<p><strong>Chest exercises</strong></p>', NULL),
+	(2, 'Biceps', NULL, NULL);
+/*!40000 ALTER TABLE `training_plan` ENABLE KEYS */;
+
+-- Struktúra mentése tábla aitrainer2. training_plan_detail
+CREATE TABLE IF NOT EXISTS `training_plan_detail` (
+  `training_plan_detail_id` int(11) NOT NULL AUTO_INCREMENT,
+  `training_plan_id` int(11) NOT NULL,
+  `exercise_type_id` int(11) NOT NULL,
+  `sort` int(3) unsigned zerofill DEFAULT NULL,
+  `set` int(3) DEFAULT NULL,
+  `repeats` int(5) DEFAULT NULL COMMENT '-1: max',
+  `weight` double DEFAULT NULL COMMENT '-1: calculated',
+  `resting_time` int(3) DEFAULT NULL,
+  `parallel` tinyint(4) DEFAULT NULL,
+  `day` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
+  PRIMARY KEY (`training_plan_detail_id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
+
+-- Tábla adatainak mentése aitrainer2.training_plan_detail: ~6 rows (hozzávetőleg)
+/*!40000 ALTER TABLE `training_plan_detail` DISABLE KEYS */;
+REPLACE INTO `training_plan_detail` (`training_plan_detail_id`, `training_plan_id`, `exercise_type_id`, `sort`, `set`, `repeats`, `weight`, `resting_time`, `parallel`, `day`) VALUES
+	(1, 1, 63, 001, 1, -1, -1, 2, 0, 'H'),
+	(2, 1, 63, 003, 1, 15, -1, 2, 0, 'H'),
+	(3, 1, 63, 004, 1, 10, 30, 2, 0, 'H'),
+	(4, 2, 39, 001, 1, 30, -1, 2, 0, 'H'),
+	(5, 1, 63, 002, 1, -1, -1, 2, 0, 'H'),
+	(6, 1, 6, 005, 1, 10, -1, 2, 0, 'H');
+/*!40000 ALTER TABLE `training_plan_detail` ENABLE KEYS */;
+
+-- Struktúra mentése tábla aitrainer2. training_plan_translation
+CREATE TABLE IF NOT EXISTS `training_plan_translation` (
+  `translation_id` int(11) NOT NULL AUTO_INCREMENT,
+  `training_plan_id` int(11) NOT NULL DEFAULT 0,
+  `name_translation` char(50) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '0',
+  `description_translation` text COLLATE utf8_hungarian_ci DEFAULT NULL,
+  `language_code` char(2) COLLATE utf8_hungarian_ci DEFAULT 'en',
+  PRIMARY KEY (`translation_id`) USING BTREE,
+  KEY `faq_id` (`training_plan_id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
+
+-- Tábla adatainak mentése aitrainer2.training_plan_translation: ~0 rows (hozzávetőleg)
+/*!40000 ALTER TABLE `training_plan_translation` DISABLE KEYS */;
+REPLACE INTO `training_plan_translation` (`translation_id`, `training_plan_id`, `name_translation`, `description_translation`, `language_code`) VALUES
+	(3, 1, 'Mell', '<pre>\r\n<strong>Mellgyakorlat m&aacute;ra</strong></pre>', 'hu');
+
 /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
 /*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
 /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
diff --git a/data/db/update_1_0_37.sql b/data/db/update_1_0_37.sql
index 992d102..72d2fea 100644
--- a/data/db/update_1_0_37.sql
+++ b/data/db/update_1_0_37.sql
@@ -3,6 +3,7 @@ START TRANSACTION;
 CREATE TABLE `training_plan` (
 	`training_plan_id` INT(11) NOT NULL AUTO_INCREMENT,
 	`name` CHAR(50) NOT NULL COLLATE 'utf8_hungarian_ci',
+	`description` TEXT NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci',
 	`type` CHAR(50) NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci',
 	PRIMARY KEY (`training_plan_id`) USING BTREE
 )
@@ -10,6 +11,19 @@ COLLATE='utf8_hungarian_ci'
 ENGINE=InnoDB
 ;
 
+CREATE TABLE `training_plan_translation` (
+	`translation_id` INT(11) NOT NULL AUTO_INCREMENT,
+	`training_plan_id` INT(11) NOT NULL DEFAULT '0',
+	`name_translation` CHAR(50) NOT NULL DEFAULT '0' COLLATE 'utf8_hungarian_ci',
+	`description_translation` TEXT NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci',
+	`language_code` CHAR(2) NULL DEFAULT 'en' COLLATE 'utf8_hungarian_ci',
+	PRIMARY KEY (`translation_id`) USING BTREE,
+	INDEX `training_plan_id` (`training_plan_id`) USING BTREE
+)
+COLLATE='utf8_hungarian_ci'
+ENGINE=InnoDB
+;
+
 CREATE TABLE `training_plan_detail` (
 	`training_plan_detail_id` INT(11) NOT NULL AUTO_INCREMENT,
 	`training_plan_id` INT(11) NOT NULL,
diff --git a/src/main/kotlin/com/aitrainer/api/ApiApplication.kt b/src/main/kotlin/com/aitrainer/api/ApiApplication.kt
index 00ffe92..0b188ad 100644
--- a/src/main/kotlin/com/aitrainer/api/ApiApplication.kt
+++ b/src/main/kotlin/com/aitrainer/api/ApiApplication.kt
@@ -1,12 +1,33 @@
 package com.aitrainer.api
 
+import org.jasypt.encryption.StringEncryptor
+import org.jasypt.encryption.pbe.PooledPBEStringEncryptor
+import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig
 import org.slf4j.LoggerFactory
 import org.springframework.boot.SpringApplication
 import org.springframework.boot.autoconfigure.SpringBootApplication
 import org.springframework.boot.builder.SpringApplicationBuilder
+import org.springframework.context.annotation.Bean
+
 
 @SpringBootApplication
-class ApiApplication
+class ApiApplication {
+    @Bean(name = ["jasyptStringEncryptor"])
+    fun stringEncryptor(): StringEncryptor? {
+        val encryptor = PooledPBEStringEncryptor()
+        val config = SimpleStringPBEConfig()
+        config.password = "Tibor"
+        config.algorithm = "PBEWithMD5AndDES"
+        config.setKeyObtentionIterations("1000")
+        config.setPoolSize("1")
+        config.providerName = "SunJCE"
+        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator")
+        config.stringOutputType = "base64"
+        encryptor.setConfig(config)
+        return encryptor
+    }
+}
+
     private val logger = LoggerFactory.getLogger(ApiApplication::class.simpleName)
 
     @Override
@@ -16,6 +37,10 @@ class ApiApplication
 
     fun main(args: Array<String>) {
         logger.info(" ---- Start aitrainer API")
-        SpringApplication.run(ApiApplication::class.java, *args)
+        val app = SpringApplication(ApiApplication::class.java)
+        app.setAdditionalProfiles("ssl")
+        app.run(*args)
     }
 
+
+
diff --git a/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt b/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt
index 6f5770f..9fc52d9 100644
--- a/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt
+++ b/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt
@@ -18,7 +18,9 @@ class CustomerPackageController( private val customerRepository: CustomerReposit
                                  private val purchaseRepository: PurchaseRepository,
                                  private val customerPropertyRepository: CustomerPropertyRepository,
                                  private val exerciseResultRepository: ExerciseResultRepository,
-                                private  val customerActivityRepository: CustomerActivityRepository) {
+                                 private val customerActivityRepository: CustomerActivityRepository,
+                                 private val customerTrainingPlanRepository: CustomerTrainingPlanRepository
+) {
 
     @GetMapping("/app_customer_package/{id}")
     fun getCustomerPackageData(@PathVariable(value = "id") customerId: Long): ResponseEntity<String> {
@@ -60,6 +62,9 @@ class CustomerPackageController( private val customerRepository: CustomerReposit
         val listActivityResult = customerActivityRepository.findByCustomerId(customerId)
         val listActivityJson = gson.toJson(listActivityResult)
 
+        val listTrainingPlan = customerTrainingPlanRepository.findAllByCustomerId(customerId)
+        val listTrainingPlanJson = gson.toJson(listTrainingPlan)
+
         val packageJson: String =
             getClassRecord(Customer::class.simpleName, customerJson) +
                     "|||" +  getClassRecord(CustomerExerciseDevice::class.simpleName, listCustomerExerciseDeviceJson) +
@@ -69,7 +74,8 @@ class CustomerPackageController( private val customerRepository: CustomerReposit
                     "|||" +  getClassRecord(CustomerProperty::class.simpleName+"All", listCustomerPropertyAllJson) +
                     "|||" +  getClassRecord(CustomerProperty::class.simpleName, listCustomerPropertyJson) +
                     "|||" +  getClassRecord(ExerciseResult::class.simpleName, listExerciseResultJson+
-                    "|||" +  getClassRecord(CustomerActivity::class.simpleName, listActivityJson))
+                    "|||" +  getClassRecord(CustomerActivity::class.simpleName, listActivityJson) +
+                    "|||" +  getClassRecord(CustomerTrainingPlan::class.simpleName, listTrainingPlanJson))
 
                     return if (packageJson.isEmpty()) ResponseEntity.notFound().build() else
             ResponseEntity.ok().body(packageJson)
diff --git a/src/main/kotlin/com/aitrainer/api/controller/CustomerTrainingPlanController.kt b/src/main/kotlin/com/aitrainer/api/controller/CustomerTrainingPlanController.kt
new file mode 100644
index 0000000..98fc904
--- /dev/null
+++ b/src/main/kotlin/com/aitrainer/api/controller/CustomerTrainingPlanController.kt
@@ -0,0 +1,38 @@
+package com.aitrainer.api.controller
+
+import com.aitrainer.api.model.CustomerProperty
+import com.aitrainer.api.model.CustomerTrainingPlan
+import com.aitrainer.api.repository.CustomerPropertyRepository
+import com.aitrainer.api.repository.CustomerTrainingPlanRepository
+import org.slf4j.LoggerFactory
+import org.springframework.http.ResponseEntity
+import org.springframework.security.access.annotation.Secured
+import org.springframework.web.bind.annotation.*
+import javax.validation.Valid
+
+@RestController
+@RequestMapping("/api")
+class CustomerTrainingPlanController(private val customerTrainingPlanRepository: CustomerTrainingPlanRepository) {
+    private val logger = LoggerFactory.getLogger(javaClass)
+
+    @PostMapping("/customer_training_plan")
+    fun createNewCustomerTrainingPlan(@Valid @RequestBody customerTrainingPlan: CustomerTrainingPlan): ResponseEntity<CustomerTrainingPlan> {
+        logger.info("Create customer property: $customerTrainingPlan")
+        return ResponseEntity.ok().body(customerTrainingPlanRepository.save(customerTrainingPlan))
+    }
+
+    @Secured
+    @PostMapping("customer_training_plan/update/{id}")
+    fun updateCustomerProperty(@PathVariable(value = "id") trainingPlanId: Long,
+                               @Valid @RequestBody customerTrainingPlanToUpdate: CustomerTrainingPlan): ResponseEntity<CustomerTrainingPlan> {
+        val customerTrainingPlan = customerTrainingPlanRepository.findById(trainingPlanId).orElse(null)
+            ?: return ResponseEntity.notFound().build()
+
+        val updatedCustomerTrainingPlan = customerTrainingPlan.copy(
+            trainingPlanId = customerTrainingPlanToUpdate.trainingPlanId,
+            customerId = customerTrainingPlanToUpdate.customerId,
+            dateAdd = customerTrainingPlanToUpdate.dateAdd
+        )
+        return ResponseEntity.ok().body(customerTrainingPlanRepository.save(updatedCustomerTrainingPlan))
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/aitrainer/api/model/CustomerTrainingPlan.kt b/src/main/kotlin/com/aitrainer/api/model/CustomerTrainingPlan.kt
new file mode 100644
index 0000000..93adf78
--- /dev/null
+++ b/src/main/kotlin/com/aitrainer/api/model/CustomerTrainingPlan.kt
@@ -0,0 +1,16 @@
+package com.aitrainer.api.model
+
+import com.google.gson.annotations.Expose
+import org.springframework.lang.NonNull
+import javax.persistence.Entity
+import javax.persistence.GeneratedValue
+import javax.persistence.GenerationType
+import javax.persistence.Id
+
+@Entity
+data class CustomerTrainingPlan (
+    @Expose @Id  @GeneratedValue(strategy = GenerationType.IDENTITY) @get: NonNull var customerTrainingPlanId: Long = 0,
+    @Expose @get: NonNull var customerId: Long = 0,
+    @Expose @get: NonNull var trainingPlanId: Long = 0,
+    @Expose @get: NonNull var dateAdd: String? = null
+)
\ No newline at end of file
diff --git a/src/main/kotlin/com/aitrainer/api/model/TrainingPlan.kt b/src/main/kotlin/com/aitrainer/api/model/TrainingPlan.kt
index e05b774..353087a 100644
--- a/src/main/kotlin/com/aitrainer/api/model/TrainingPlan.kt
+++ b/src/main/kotlin/com/aitrainer/api/model/TrainingPlan.kt
@@ -11,10 +11,15 @@ import javax.validation.constraints.NotBlank
 data class TrainingPlan (
     @Expose @Id  @GeneratedValue(strategy = GenerationType.IDENTITY) @get: NonNull  var trainingPlanId: Long = 0,
     @Expose @get: NotBlank  var name: String = "",
+    @Expose var description: String?,
     @Expose @get: NotBlank  var type: String = "",
 ) {
-        @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER, mappedBy = "trainingPlan")
-        @Fetch(value = FetchMode.SUBSELECT)
-        @Expose val details: List<TrainingPlanDetail> = mutableListOf<TrainingPlanDetail>().toList()
+    @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER, mappedBy = "trainingPlan")
+    @Fetch(value = FetchMode.SUBSELECT)
+    @Expose val details: List<TrainingPlanDetail> = mutableListOf<TrainingPlanDetail>().toList()
+
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "trainingPlan")
+    @Fetch(value = FetchMode.SUBSELECT)
+    @Expose val translations: List<TrainingPlanTranslation> = mutableListOf<TrainingPlanTranslation>()
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/aitrainer/api/model/TrainingPlanDetail.kt b/src/main/kotlin/com/aitrainer/api/model/TrainingPlanDetail.kt
index 8a8f992..8529d9b 100644
--- a/src/main/kotlin/com/aitrainer/api/model/TrainingPlanDetail.kt
+++ b/src/main/kotlin/com/aitrainer/api/model/TrainingPlanDetail.kt
@@ -11,11 +11,11 @@ data class TrainingPlanDetail (
     @Expose @Id  @GeneratedValue(strategy = GenerationType.IDENTITY) @get: NonNull var trainingPlanDetailId: Long = 0,
     @Expose @get: NotBlank var exerciseTypeId: Int = 0,
     @Expose @get: NotBlank var sort: Int = 0,
-    @Expose @get: NotBlank var set: Int = 0,
-    @Expose @get: NotBlank var repeats: Int = 0,
-    @Expose @get: NotBlank var weight: Double = 0.0,
-    @Expose @get: NotBlank var restingTime: Int = 0,
-    @Expose @get: NotBlank var parallel: Boolean = false,
+    @Expose var set: Int = 0,
+    @Expose var repeats: Int? = 0,
+    @Expose var weight: Double? = 0.0,
+    @Expose var restingTime: Int? = 0,
+    @Expose var parallel: Boolean? = false,
     @Expose var day: String? = null,
 
 ) {
@@ -24,7 +24,4 @@ data class TrainingPlanDetail (
     @JoinColumn(name = "trainingPlanId", nullable = false)
     @JsonIgnore
     val trainingPlan: TrainingPlan? = null
-
-
-
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/aitrainer/api/model/TrainingPlanTranslation.kt b/src/main/kotlin/com/aitrainer/api/model/TrainingPlanTranslation.kt
new file mode 100644
index 0000000..20b1414
--- /dev/null
+++ b/src/main/kotlin/com/aitrainer/api/model/TrainingPlanTranslation.kt
@@ -0,0 +1,23 @@
+package com.aitrainer.api.model
+
+import com.fasterxml.jackson.annotation.JsonIgnore
+import com.google.gson.annotations.Expose
+import javax.persistence.*
+import javax.validation.constraints.NotBlank
+
+@Entity
+data class TrainingPlanTranslation (
+        @Expose @Id  @GeneratedValue(strategy = GenerationType.IDENTITY)  val translationId: Long = 0,
+
+        @Expose @get: NotBlank var languageCode: String?,
+        @Expose @get: NotBlank var nameTranslation: String = "",
+        @Expose @get: NotBlank var descriptionTranslation: String = "",
+
+
+) {
+        @ManyToOne(fetch = FetchType.EAGER, optional = false)
+        @JoinColumn(name = "trainingPlanId", nullable = false)
+        @JsonIgnore
+        val trainingPlan: TrainingPlan? = null
+
+}
diff --git a/src/main/kotlin/com/aitrainer/api/repository/CustomerTrainingPlanRepository.kt b/src/main/kotlin/com/aitrainer/api/repository/CustomerTrainingPlanRepository.kt
new file mode 100644
index 0000000..f23e335
--- /dev/null
+++ b/src/main/kotlin/com/aitrainer/api/repository/CustomerTrainingPlanRepository.kt
@@ -0,0 +1,10 @@
+package com.aitrainer.api.repository
+
+import com.aitrainer.api.model.CustomerTrainingPlan
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface CustomerTrainingPlanRepository: JpaRepository<CustomerTrainingPlan, Long> {
+    fun findAllByCustomerId(customerId: Long): List<CustomerTrainingPlan>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/aitrainer/api/service/AppConfigJasyptStarter.kt b/src/main/kotlin/com/aitrainer/api/service/AppConfigJasyptStarter.kt
new file mode 100644
index 0000000..4facb0d
--- /dev/null
+++ b/src/main/kotlin/com/aitrainer/api/service/AppConfigJasyptStarter.kt
@@ -0,0 +1,9 @@
+package com.aitrainer.api.service
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.context.annotation.PropertySource
+
+@Configuration
+@PropertySource("classpath:application.ssl.properties")
+class AppConfigForJasyptStarter {
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/aitrainer/api/service/PropertyServiceForJasyptStarter.kt b/src/main/kotlin/com/aitrainer/api/service/PropertyServiceForJasyptStarter.kt
new file mode 100644
index 0000000..aa9f4e5
--- /dev/null
+++ b/src/main/kotlin/com/aitrainer/api/service/PropertyServiceForJasyptStarter.kt
@@ -0,0 +1,24 @@
+package com.aitrainer.api.service
+
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.core.env.Environment
+import org.springframework.stereotype.Service
+
+@Service
+class PropertyServiceForJasyptStarter {
+    @Value("\${trust.store.password}")
+    val storePassword: String? = null
+
+
+   @Value("\${server.ssl.key-store-password}")
+   val keyStorePassword: String? = null
+
+
+    fun getPasswordUsingEnvironment(environment: Environment): String? {
+        return environment.getProperty("trust.store.password")
+    }
+
+    fun getKeyStorePasswordUsingEnvironment(environment: Environment): String? {
+        return environment.getProperty("server.ssl.key-store-password")
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 3a2fa50..17dbf65 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -19,4 +19,5 @@ logging.file=logs
 # if the database structure has been changed, increment this version number
 application.version=1.0.37
 
-jwt.secret=aitrainer
\ No newline at end of file
+jwt.secret=aitrainer
+jasypt.encryptor.password=Tibor
diff --git a/src/main/resources/application.ssl.properties b/src/main/resources/application.ssl.properties
new file mode 100644
index 0000000..a0d7cd4
--- /dev/null
+++ b/src/main/resources/application.ssl.properties
@@ -0,0 +1,19 @@
+http.port=8088
+server.port=8443
+server.ssl.enabled=true
+
+jasypt.encryptor.bean=jasyptStringEncryptor
+# The format used for the keystore. It could be set to JKS in case it is a JKS file
+server.ssl.key-store-type=PKCS12
+# The path to the keystore containing the certificate
+server.ssl.key-store=classpath:keystore/aitrainer_server.p12
+# The password used to generate the certificate
+server.ssl.key-store-password=ENC(aI6iP8wGJ9dwIA+hKabwK/VDXe4NOrhl)
+# The alias mapped to the certificate
+server.ssl.key-alias=aitrainer_server
+
+
+#trust store location
+trust.store=classpath:keystore/aitrainer_server.p12
+#trust store password
+trust.store.password=ENC(aI6iP8wGJ9dwIA+hKabwK/VDXe4NOrhl)
diff --git a/src/main/resources/keystore/aitrainer_server.p12 b/src/main/resources/keystore/aitrainer_server.p12
new file mode 100644
index 0000000..f2d561d
Binary files /dev/null and b/src/main/resources/keystore/aitrainer_server.p12 differ
diff --git a/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt b/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt
index 7862b14..811d39c 100644
--- a/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt
+++ b/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt
@@ -42,13 +42,16 @@ class AppCustomerPackageTest {
     @Autowired
     private lateinit var customerActivityRepository: CustomerActivityRepository
 
+    @Autowired
+    private lateinit var customerTrainingPlanRepository: CustomerTrainingPlanRepository
+
     @Test
     fun customerPackageTest() {
         val gson = Gson()
 
         val controller = CustomerPackageController(customerRepository, customerExerciseDeviceRepository,
             exercisesRepository, productTestRepository, purchaseRepository, customerPropertyRepository,
-            exerciseResultRepository, customerActivityRepository )
+            exerciseResultRepository, customerActivityRepository, customerTrainingPlanRepository )
         var response: ResponseEntity<*> = controller.getCustomerPackageData(91)
         assertEquals(response.statusCode, HttpStatus.NOT_FOUND)
 
@@ -118,6 +121,14 @@ class AppCustomerPackageTest {
                     assertTrue(activityList.isNotEmpty())
                     assertEquals(activityList[0].type,"basic_tutorial")
                 }
+                record[0] == CustomerTrainingPlan::class.simpleName+"All" -> {
+                    val trainingPlanJson: String = record[1]
+                    val type = object : TypeToken<List<CustomerTrainingPlan?>?>() {}.type
+                    val trainingPlanList: List<CustomerTrainingPlan> = gson.fromJson(trainingPlanJson, type)
+                    assertTrue(trainingPlanList.isNotEmpty())
+                    assertEquals(trainingPlanList[0].customerId,91)
+                    assertEquals(trainingPlanList[0].trainingPlanId,2)
+                }
             }
         }
 
diff --git a/src/test/kotlin/com/aitrainer/api/test/CustomerTrainingPlanTest.kt b/src/test/kotlin/com/aitrainer/api/test/CustomerTrainingPlanTest.kt
new file mode 100644
index 0000000..4de04e7
--- /dev/null
+++ b/src/test/kotlin/com/aitrainer/api/test/CustomerTrainingPlanTest.kt
@@ -0,0 +1,44 @@
+package com.aitrainer.api.test
+
+
+import com.aitrainer.api.controller.CustomerTrainingPlanController
+import com.aitrainer.api.model.CustomerTrainingPlan
+import com.aitrainer.api.repository.CustomerTrainingPlanRepository
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInstance
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+
+@SpringBootTest
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class CustomerTrainingPlanTest {
+
+    @Autowired
+    private lateinit var customerTrainingPlanRepository: CustomerTrainingPlanRepository
+
+
+
+    @Test
+    fun testInsert() {
+        val customerTrainingPlan = CustomerTrainingPlan(
+            customerId = 90,
+            trainingPlanId = 1,
+            dateAdd = "2021-05-12",
+
+        )
+
+        val controller = CustomerTrainingPlanController(customerTrainingPlanRepository)
+        val response = controller.createNewCustomerTrainingPlan(customerTrainingPlan)
+
+        val newCustomerTrainingPlan = response.body
+
+        assertTrue(newCustomerTrainingPlan is CustomerTrainingPlan)
+        assertEquals(newCustomerTrainingPlan.dateAdd, "2021-05-12")
+
+        customerTrainingPlanRepository.delete(newCustomerTrainingPlan)
+    }
+
+
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/aitrainer/api/test/HttpsApplicationIntegrationTest.kt b/src/test/kotlin/com/aitrainer/api/test/HttpsApplicationIntegrationTest.kt
new file mode 100644
index 0000000..300e405
--- /dev/null
+++ b/src/test/kotlin/com/aitrainer/api/test/HttpsApplicationIntegrationTest.kt
@@ -0,0 +1,120 @@
+package com.aitrainer.api.test
+
+import com.aitrainer.api.ApiApplication
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInstance
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.core.io.Resource
+import org.springframework.http.HttpStatus
+import org.springframework.test.context.ActiveProfiles
+import org.springframework.test.context.junit4.SpringRunner
+import java.io.FileInputStream
+import java.net.URI
+import java.security.KeyStore
+import java.security.cert.X509Certificate
+import java.time.Duration
+import javax.net.ssl.KeyManagerFactory
+import javax.net.ssl.SSLContext
+import javax.net.ssl.TrustManager
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+
+
+/*@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@RunWith(SpringRunner::class)
+@SpringBootTest(classes = [ApiApplication::class], webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+@ActiveProfiles("ssl")*/
+class HttpsApplicationIntegrationTest {
+/*    @Value("\${trust.store}")
+    @Autowired
+    private lateinit var trustStore: Resource
+
+    @Value("\${trust.store.password}")
+    @Autowired
+    private lateinit var trustStorePassword: String*/
+/*
+
+    fun buildClient(): HttpClient? {
+        val ks = KeyStore.getInstance("pkcs12")
+        val kmf = KeyManagerFactory.getInstance("SunX509")
+        //create new ssl context
+        val sslContext = SSLContext.getInstance("SSL")
+        //load your file to keystore
+        ks.load(FileInputStream(trustStore.file.toString()), trustStorePassword.toCharArray())
+        kmf.init(ks, trustStorePassword.toCharArray())
+        //set global system properties
+        System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol")
+        System.setProperty("javax.net.ssl.keyStoreType", "pkcs12")
+        System.setProperty("javax.net.ssl.keyStore", trustStorePassword)
+        System.setProperty("javax.net.ssl.keyStorePassword", trustStorePassword)
+
+        //initialize sslContext
+        sslContext.init(kmf.keyManagers, getTrustAllCert(), null)
+
+        val client = HttpClient.newBuilder()
+            .connectTimeout(Duration.ofSeconds(10))
+            .sslContext(sslContext)
+
+            .build()
+        //you can send request with your ssl certificate
+        return client
+    }
+
+    private fun getTrustAllCert(): Array<TrustManager> {
+
+        return arrayOf(object : javax.net.ssl.X509TrustManager {
+            override fun getAcceptedIssuers(): Array<X509Certificate>? = null
+            override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) {}
+            override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) {}
+        })
+    }
+
+    @Test
+    fun testSSL() {
+        val httpClient: HttpClient? = buildClient()
+        if ( httpClient == null) {
+            assertTrue(false)
+        }
+        val request = HttpRequest.newBuilder()
+            .uri(URI.create(WELCOME_URL))
+            .build()
+
+
+        val response = httpClient!!.send(request, HttpResponse.BodyHandlers.ofString());
+        assertEquals(response.statusCode(), HttpStatus.OK)
+        println(response.body())
+
+    }
+*/
+
+   /* @Test
+    @Throws(Exception::class)
+    fun whenGETanHTTPSResource_thenCorrectResponse() {
+        val response = restTemplate().getForEntity(
+            WELCOME_URL,
+            String::class.java, Collections.emptyMap()
+        )
+        assertEquals("<h1>Welcome to Secured Site</h1>", response.body)
+        assertEquals(HttpStatus.OK, response.statusCode)
+    }
+
+    @Throws(Exception::class)
+    fun restTemplate(): RestTemplate {
+        val sslContext: SSLContext =
+            SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword!!.toCharArray())
+                .build()
+        val socketFactory = SSLConnectionSocketFactory(sslContext)
+        val httpClient: HttpClient = HttpClients.custom()
+            .setSSLSocketFactory(socketFactory)
+            .build()
+        val factory = HttpComponentsClientHttpRequestFactory(httpClient)
+        return RestTemplate(factory)
+    }*/
+
+    companion object {
+        private const val WELCOME_URL = "https://localhost:8443/api/welcome"
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/aitrainer/api/test/JasyptTest.kt b/src/test/kotlin/com/aitrainer/api/test/JasyptTest.kt
new file mode 100644
index 0000000..46849db
--- /dev/null
+++ b/src/test/kotlin/com/aitrainer/api/test/JasyptTest.kt
@@ -0,0 +1,57 @@
+package com.aitrainer.api.test
+
+import com.aitrainer.api.service.PropertyServiceForJasyptStarter
+import org.jasypt.encryption.StringEncryptor
+import org.jasypt.encryption.pbe.PooledPBEStringEncryptor
+import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInstance
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.context.ApplicationContext
+import org.springframework.core.env.Environment
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+
+
+@SpringBootTest
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class JasyptTest {
+    @Autowired
+    private lateinit var appCtx: ApplicationContext
+
+    @Test
+    fun testPassword() {
+
+        val passwordEncryptor = getEncryptor()
+        val encryptedPassword = passwordEncryptor.encrypt("xxx")
+        println(encryptedPassword)
+        assertFalse("xxx" == encryptedPassword);
+    }
+
+    fun getEncryptor(): StringEncryptor {
+        val encryptor = PooledPBEStringEncryptor()
+        val config = SimpleStringPBEConfig()
+        config.password = "Tibor"
+        config.algorithm = "PBEWithMD5AndDES"
+        config.setKeyObtentionIterations("1000")
+        config.setPoolSize("1")
+        config.providerName = "SunJCE"
+        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator")
+        config.stringOutputType = "base64"
+        encryptor.setConfig(config)
+        return encryptor
+    }
+     //@Test
+     fun whenDecryptedPasswordNeeded_GetFromService() {
+         System.setProperty("jasypt.encryptor.password", "Tibor")
+         val service: PropertyServiceForJasyptStarter = appCtx
+             .getBean(PropertyServiceForJasyptStarter::class.java)
+         assertEquals("xxx", service.storePassword)
+         val environment: Environment = appCtx.getBean(Environment::class.java)
+         assertEquals(
+             "xxx",
+             service.getPasswordUsingEnvironment(environment)
+         )
+     }
+}
\ No newline at end of file