diff --git a/app/models/user/with_authentication.rb b/app/models/user/with_authentication.rb
index 5e77a816e70466df1ade64dd6779008a2119ccdb..1ff79412d4b758db069ad19be7fdf26d3c499707 100644
--- a/app/models/user/with_authentication.rb
+++ b/app/models/user/with_authentication.rb
@@ -7,8 +7,9 @@ module User::WithAuthentication
 
     has_one_time_password(encrypted: true)
 
-    validates_presence_of :email
+    validates_presence_of :first_name, :last_name, :email
     validates :role, presence: true
+    validate :password_complexity
     validates :mobile_phone, format: { with: /\A\+[0-9]+\z/ }, allow_blank: true
 
     before_validation :adjust_mobile_phone, :sanitize_fields
@@ -62,5 +63,11 @@ module User::WithAuthentication
       self.last_name = full_sanitizer.sanitize(self.last_name)&.gsub('=', '')
       self.mobile_phone = full_sanitizer.sanitize(self.mobile_phone)&.gsub('=', '')
     end
+
+    def password_complexity
+      # Regexp extracted from https://stackoverflow.com/questions/19605150/regex-for-password-must-contain-at-least-eight-characters-at-least-one-number-a
+      return if password.blank? || password =~ /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#{Rails.application.config.allowed_special_chars}]).{#{Devise.password_length.first},#{Devise.password_length.last}}$/
+      errors.add :password, I18n.t('activerecord.errors.models.user.password.password_strength')
+    end
   end
 end
diff --git a/config/application.rb b/config/application.rb
index c8b10596169693a79afd3eee81d83b7f45d11a0f..0261f910bbfcd35f75b987cd4d6ce5e58f408984 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -48,6 +48,11 @@ module Osuny
         authentication: :plain
     }
 
+    config.action_view.sanitized_allowed_tags = ['strong', 'em', 'b', 'i', 'u', 'p', 'code', 'pre', 'tt', 'samp', 'kbd', 'var', 'sub', 'sup', 'dfn', 'cite', 'big', 'small', 'address', 'hr', 'br', 'div', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'abbr', 'acronym', 'a', 'img', 'blockquote', 'del', 'ins']
+    config.action_view.sanitized_allowed_attributes = ['href', 'src', 'srcset', 'width', 'height', 'alt', 'cite', 'datetime', 'title', 'class', 'name', 'xml:lang', 'abbr', 'style', 'target']
+
+    config.allowed_special_chars = '#?!,@$%^&*+£µ-'
+
     config.generators do |g|
       g.orm :active_record, primary_key_type: :uuid
     end
diff --git a/db/schema.rb b/db/schema.rb
index 6c4146d71072c9303f6e5d50a7f310d81ea8a4cc..1f77195c1707a9db98616fdc9183015813e2a96b 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -213,7 +213,7 @@ ActiveRecord::Schema.define(version: 2021_10_08_152623) do
     t.uuid "research_journal_id", null: false
     t.uuid "research_journal_volume_id"
     t.datetime "created_at", precision: 6, null: false
-    t.date "updated_at", null: false
+    t.datetime "updated_at", precision: 6, null: false
     t.uuid "updated_by_id"
     t.text "abstract"
     t.text "references"
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000000000000000000000000000000000000..fb57ccd13afbd082ad82051c2ffebef4840661ec
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,4 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+