diff --git a/client/components/admin/admin-general.vue b/client/components/admin/admin-general.vue
index 50eff359..52b90005 100644
--- a/client/components/admin/admin-general.vue
+++ b/client/components/admin/admin-general.vue
@@ -163,6 +163,7 @@
                     persistent-hint
                     hint='Prevents other websites from embedding your wiki in an iframe. This provides clickjacking protection.'
                     )
+
                   v-divider.mt-3
                   v-switch(
                     inset
@@ -173,6 +174,16 @@
                     hint='Limits the referrer header to same origin.'
                     )
 
+                  v-divider.mt-3
+                  v-switch(
+                    inset
+                    label='Trust X-Forwarded-* Proxy Headers'
+                    color='red darken-2'
+                    v-model='config.securityTrustProxy'
+                    persistent-hint
+                    hint='Should be enabled when using a reverse-proxy like nginx, apache, CloudFlare, etc in front of Wiki.js. Turn off otherwise.'
+                    )
+
                   v-divider.mt-3
                   v-switch(
                     inset
@@ -250,6 +261,7 @@ export default {
         featureTinyPNG: false,
         securityIframe: true,
         securityReferrerPolicy: true,
+        securityTrustProxy: true,
         securityHSTS: false,
         securityHSTSDuration: 0,
         securityCSP: false,
@@ -296,6 +308,7 @@ export default {
             featurePersonalWikis: _.get(this.config, 'featurePersonalWikis', false),
             securityIframe: _.get(this.config, 'securityIframe', false),
             securityReferrerPolicy: _.get(this.config, 'securityReferrerPolicy', false),
+            securityTrustProxy: _.get(this.config, 'securityTrustProxy', false),
             securityHSTS: _.get(this.config, 'securityHSTS', false),
             securityHSTSDuration: _.get(this.config, 'securityHSTSDuration', 0),
             securityCSP: _.get(this.config, 'securityCSP', false),
diff --git a/client/components/admin/admin-groups-edit.vue b/client/components/admin/admin-groups-edit.vue
index 2e647bac..9ee23b45 100644
--- a/client/components/admin/admin-groups-edit.vue
+++ b/client/components/admin/admin-groups-edit.vue
@@ -18,7 +18,7 @@
                 v-icon(color='red') mdi-trash-can-outline
             v-card
               .dialog-header.is-red Delete Group?
-              v-card-text Are you sure you want to delete group #[strong {{ group.name }}]? All users will be unassigned from this group.
+              v-card-text.pa-4 Are you sure you want to delete group #[strong {{ group.name }}]? All users will be unassigned from this group.
               v-card-actions
                 v-spacer
                 v-btn(text, @click='deleteGroupDialog = false') Cancel
diff --git a/client/components/admin/admin-utilities-importv1.vue b/client/components/admin/admin-utilities-importv1.vue
index 991e1c8e..fdd2ea64 100644
--- a/client/components/admin/admin-utilities-importv1.vue
+++ b/client/components/admin/admin-utilities-importv1.vue
@@ -63,7 +63,7 @@
             v-col(v-if='gitAuthMode === `ssh`', cols='12')
               v-textarea(
                 outlined
-                label='Private Key'
+                label='Private Key Contents'
                 placeholder='-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----'
                 hide-details
                 v-model='gitPrivKey'
@@ -72,7 +72,7 @@
               v-col(cols='6')
                 v-text-field(
                   label='Username'
-                  v-model='gitUserEmail'
+                  v-model='gitUsername'
                   outlined
                   hide-details
                 )
@@ -80,7 +80,7 @@
                 v-text-field(
                   type='password'
                   label='Password / PAT'
-                  v-model='gitUserName'
+                  v-model='gitPassword'
                   outlined
                   hide-details
                 )
@@ -108,10 +108,14 @@
                 outlined
                 hide-details
               )
+              .caption.mt-2 This folder should be empty or not exist yet. #[strong.deep-orange--text.text--darken-2 DO NOT] point to your existing Wiki.js 1.x repository folder. In most cases, it should be left to the default value.
+          v-alert(color='deep-orange', outlined, icon='mdi-alert', prominent)
+            .body-2 - Note that if you already configured the git storage module, its configuration will be replaced with the above.
+            .body-2 - Although both v1 and v2 installations can use the same remote git repository, you shouldn't make edits to the same pages simultaneously.
         v-radio-group(v-model='contentMode', hide-details)
           v-divider
           v-radio.mt-3(
-            value='local'
+            value='disk'
             color='primary'
             )
             template(v-slot:label)
@@ -152,7 +156,7 @@
             template(v-slot:label)
               div
                 span Create groups for each unique user permissions configuration
-                .caption: em Note that this can result in a large amount of groups being created.
+                .caption: em #[strong.primary--text Recommended] | Users having identical permission sets will be assigned to the same group. Note that this can potentially result in a large amount of groups being created.
           v-divider
           v-radio.mt-3(
             value='SINGLE'
@@ -161,7 +165,7 @@
             template(v-slot:label)
               div
                 span Create a single group with all imported users
-                .caption: em #[strong.primary--text Recommended] | The new group will have read permissions enabled by default.
+                .caption: em The new group will have read permissions enabled by default.
           v-divider
           v-radio.mt-3(
             value='NONE'
@@ -172,6 +176,10 @@
                 span Don't create any group
                 .caption: em Users will not be able to access your wiki until they are assigned to a group.
 
+        v-alert.mt-5(color='deep-orange', outlined, icon='mdi-alert', prominent)
+          .body-2 Note that any user that already exists in this installation will not be imported. A list of skipped users will be displayed upon completion.
+          .caption.grey--text You must first delete from this installation any user you want to migrate over from the old installation.
+
     v-card-chin
       v-btn.px-3(depressed, color='deep-orange darken-2', :disabled='!wantUsers && !wantContent', @click='startImport').ml-0
         v-icon(left, color='white') mdi-database-import
@@ -220,9 +228,6 @@
                 v-icon(left) mdi-alert
                 span {{failedUsers.length}} failed
             .body-2 #[strong {{successGroups}}] groups created
-          template(v-if='wantContent')
-            .body-2 #[strong {{successPages}}] pages
-            .body-2 #[strong {{successAssets}}] assets
         v-card-actions.green.darken-1
           v-spacer
           v-btn.px-5(
@@ -266,6 +271,10 @@ import _ from 'lodash'
 import { SemipolarSpinner } from 'epic-spinners'
 
 import utilityImportv1UsersMutation from 'gql/admin/utilities/utilities-mutation-importv1-users.gql'
+import storageTargetsQuery from 'gql/admin/storage/storage-query-targets.gql'
+import storageStatusQuery from 'gql/admin/storage/storage-query-status.gql'
+import targetExecuteActionMutation from 'gql/admin/storage/storage-mutation-executeaction.gql'
+import targetsSaveMutation from 'gql/admin/storage/storage-mutation-save-targets.gql'
 
 export default {
   components: {
@@ -274,7 +283,7 @@ export default {
   data() {
     return {
       importFilters: ['content', 'users'],
-      groupMode: 'SINGLE',
+      groupMode: 'MULTI',
       contentMode: 'git',
       dbConnStr: 'mongodb://',
       contentPath: '/wiki-v1/repo',
@@ -289,14 +298,14 @@ export default {
       gitRepoUrl: '',
       gitRepoBranch: 'master',
       gitPrivKey: '',
+      gitUsername: '',
+      gitPassword: '',
       gitUserEmail: '',
       gitUserName: '',
       gitRepoPath: './data/repo',
       progress: 0,
       successUsers: 0,
       successPages: 0,
-      successGroups: 0,
-      successAssets: 0,
       showFailedUsers: false,
       failedUsers: []
     }
@@ -321,40 +330,161 @@ export default {
       this.progress = 0
       this.failedUsers = []
 
-      // -> Import Users
+      _.delay(async () => {
+        // -> Import Users
 
-      if (this.wantUsers) {
-        try {
-          const resp = await this.$apollo.mutate({
-            mutation: utilityImportv1UsersMutation,
-            variables: {
-              mongoDbConnString: this.dbConnStr,
-              groupMode: this.groupMode
+        if (this.wantUsers) {
+          try {
+            const resp = await this.$apollo.mutate({
+              mutation: utilityImportv1UsersMutation,
+              variables: {
+                mongoDbConnString: this.dbConnStr,
+                groupMode: this.groupMode
+              }
+            })
+            const respObj = _.get(resp, 'data.system.importUsersFromV1', {})
+            if (!_.get(respObj, 'responseResult.succeeded', false)) {
+              throw new Error(_.get(respObj, 'responseResult.message', 'An unexpected error occured'))
             }
-          })
-          const respObj = _.get(resp, 'data.system.importUsersFromV1', {})
-          if (!_.get(respObj, 'responseResult.succeeded', false)) {
-            throw new Error(_.get(respObj, 'responseResult.message', 'An unexpected error occured'))
+            this.successUsers = _.get(respObj, 'usersCount', 0)
+            this.successGroups = _.get(respObj, 'groupsCount', 0)
+            this.failedUsers = _.get(respObj, 'failed', [])
+            this.progress += 50
+          } catch (err) {
+            this.$store.commit('pushGraphError', err)
+            this.isLoading = false
+            return
           }
-          this.successUsers = _.get(respObj, 'usersCount', 0)
-          this.successGroups = _.get(respObj, 'groupsCount', 0)
-          this.failedUsers = _.get(respObj, 'failed', [])
-          this.progress += 50
-        } catch (err) {
-          this.$store.commit('pushGraphError', err)
-          this.isLoading = false
-          return
         }
-      }
 
-      // -> Import Content
+        // -> Import Content
+
+        if (this.wantContent) {
+          try {
+            const resp = await this.$apollo.query({
+              query: storageTargetsQuery,
+              fetchPolicy: 'network-only'
+            })
+            if (_.has(resp, 'data.storage.targets')) {
+              this.progress += 10
+              let targets = resp.data.storage.targets.map(str => {
+                let nStr = {
+                  ...str,
+                  config: _.sortBy(str.config.map(cfg => ({
+                    ...cfg,
+                    value: JSON.parse(cfg.value)
+                  })), [t => t.value.order])
+                }
+
+                // -> Setup Git Module
+
+                if (this.contentMode === 'git' && nStr.key === 'git') {
+                  nStr.isEnabled = true
+                  nStr.mode = 'sync'
+                  nStr.syncInterval = 'PT5M'
+                  nStr.config = [
+                    { key: 'authType', value: { value: this.gitAuthMode } },
+                    { key: 'repoUrl', value: { value: this.gitRepoUrl } },
+                    { key: 'branch', value: { value: this.gitRepoBranch } },
+                    { key: 'sshPrivateKeyMode', value: { value: 'contents' } },
+                    { key: 'sshPrivateKeyPath', value: { value: '' } },
+                    { key: 'sshPrivateKeyContent', value: { value: this.gitPrivKey } },
+                    { key: 'verifySSL', value: { value: this.gitVerifySSL } },
+                    { key: 'basicUsername', value: { value: this.gitUsername } },
+                    { key: 'basicPassword', value: { value: this.gitPassword } },
+                    { key: 'defaultEmail', value: { value: this.gitUserEmail } },
+                    { key: 'defaultName', value: { value: this.gitUserName } },
+                    { key: 'localRepoPath', value: { value: this.gitRepoPath } },
+                    { key: 'gitBinaryPath', value: { value: '' } }
+                  ]
+                }
+                return nStr
+              })
+
+              // -> Save storage modules configuration
+
+              const respSv = await this.$apollo.mutate({
+                mutation: targetsSaveMutation,
+                variables: {
+                  targets: targets.map(tgt => _.pick(tgt, [
+                    'isEnabled',
+                    'key',
+                    'config',
+                    'mode',
+                    'syncInterval'
+                  ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: JSON.stringify({ v: cfg.value.value })}))}))
+                }
+              })
+              const respObj = _.get(respSv, 'data.storage.updateTargets', {})
+              if (!_.get(respObj, 'responseResult.succeeded', false)) {
+                throw new Error(_.get(respObj, 'responseResult.message', 'An unexpected error occured'))
+              }
+
+              this.progress += 10
+
+              // -> Wait for success sync
 
-      if (this.wantContent) {
+              let statusAttempts = 0
+              while (statusAttempts < 10) {
+                statusAttempts++
+                const respStatus = await this.$apollo.query({
+                  query: storageStatusQuery,
+                  fetchPolicy: 'network-only'
+                })
+                if (_.has(respStatus, 'data.storage.status[0]')) {
+                  const st = _.find(respStatus.data.storage.status, ['key', this.contentMode])
+                  if (!st) {
+                    throw new Error('Storage target could not be configured.')
+                  }
+                  switch (st.status) {
+                    case 'pending':
+                      if (statusAttempts >= 10) {
+                        throw new Error('Storage target is stuck in pending state. Try again.')
+                      } else {
+                        continue
+                      }
+                    case 'operational':
+                      statusAttempts = 10
+                      break
+                    case 'error':
+                      throw new Error(st.message)
+                  }
+                } else {
+                  throw new Error('Failed to fetch storage sync status.')
+                }
+              }
 
-      }
+              this.progress += 15
+
+              // -> Perform import all
+
+              const respImport = await this.$apollo.mutate({
+                mutation: targetExecuteActionMutation,
+                variables: {
+                  targetKey: this.contentMode,
+                  handler: 'importAll'
+                }
+              })
+
+              const respImportObj = _.get(respImport, 'data.storage.executeAction', {})
+              if (!_.get(respImportObj, 'responseResult.succeeded', false)) {
+                throw new Error(_.get(respImportObj, 'responseResult.message', 'An unexpected error occured'))
+              }
+
+              this.progress += 15
+            } else {
+              throw new Error('Failed to fetch storage targets.')
+            }
+          } catch (err) {
+            this.$store.commit('pushGraphError', err)
+            this.isLoading = false
+            return
+          }
+        }
 
-      this.isLoading = false
-      this.isSuccess = true
+        this.isLoading = false
+        this.isSuccess = true
+      }, 1500)
     }
   }
 }
diff --git a/client/graph/admin/site/site-mutation-save-config.gql b/client/graph/admin/site/site-mutation-save-config.gql
index 172eaec2..87730501 100644
--- a/client/graph/admin/site/site-mutation-save-config.gql
+++ b/client/graph/admin/site/site-mutation-save-config.gql
@@ -13,6 +13,7 @@ mutation (
   $featurePersonalWikis: Boolean!
   $securityIframe: Boolean!
   $securityReferrerPolicy: Boolean!
+  $securityTrustProxy: Boolean!
   $securityHSTS: Boolean!
   $securityHSTSDuration: Int!
   $securityCSP: Boolean!
@@ -34,6 +35,7 @@ mutation (
       featurePersonalWikis: $featurePersonalWikis,
       securityIframe: $securityIframe,
       securityReferrerPolicy: $securityReferrerPolicy,
+      securityTrustProxy: $securityTrustProxy,
       securityHSTS: $securityHSTS,
       securityHSTSDuration: $securityHSTSDuration,
       securityCSP: $securityCSP,
diff --git a/client/graph/admin/site/site-query-config.gql b/client/graph/admin/site/site-query-config.gql
index 3b62ff0b..5af45d09 100644
--- a/client/graph/admin/site/site-query-config.gql
+++ b/client/graph/admin/site/site-query-config.gql
@@ -15,6 +15,7 @@
       featurePersonalWikis
       securityIframe
       securityReferrerPolicy
+      securityTrustProxy
       securityHSTS
       securityHSTSDuration
       securityCSP
diff --git a/server/app/data.yml b/server/app/data.yml
index 3ddf1231..2447cd89 100644
--- a/server/app/data.yml
+++ b/server/app/data.yml
@@ -45,6 +45,7 @@ defaults:
     security:
       securityIframe: true
       securityReferrerPolicy: true
+      securityTrustProxy: true
       securityHSTS: false
       securityHSTSDuration: 300
       securityCSP: false
diff --git a/server/graph/resolvers/site.js b/server/graph/resolvers/site.js
index 94000741..f4cad189 100644
--- a/server/graph/resolvers/site.js
+++ b/server/graph/resolvers/site.js
@@ -46,6 +46,7 @@ module.exports = {
         WIKI.config.security = {
           securityIframe: args.securityIframe,
           securityReferrerPolicy: args.securityReferrerPolicy,
+          securityTrustProxy: args.securityTrustProxy,
           securityHSTS: args.securityHSTS,
           securityHSTSDuration: args.securityHSTSDuration,
           securityCSP: args.securityCSP,
@@ -53,6 +54,12 @@ module.exports = {
         }
         await WIKI.configSvc.saveToDb(['host', 'title', 'company', 'seo', 'logo', 'features', 'security'])
 
+        if (WIKI.config.security.securityTrustProxy) {
+          WIKI.app.enable('trust proxy')
+        } else {
+          WIKI.app.disable('trust proxy')
+        }
+
         return {
           responseResult: graphHelper.generateSuccess('Site configuration updated successfully')
         }
diff --git a/server/graph/schemas/site.graphql b/server/graph/schemas/site.graphql
index 5cc573d6..0ce83ac5 100644
--- a/server/graph/schemas/site.graphql
+++ b/server/graph/schemas/site.graphql
@@ -38,6 +38,7 @@ type SiteMutation {
     featurePersonalWikis: Boolean!
     securityIframe: Boolean!
     securityReferrerPolicy: Boolean!
+    securityTrustProxy: Boolean!
     securityHSTS: Boolean!
     securityHSTSDuration: Int!
     securityCSP: Boolean!
@@ -64,6 +65,7 @@ type SiteConfig {
   featurePersonalWikis: Boolean!
   securityIframe: Boolean!
   securityReferrerPolicy: Boolean!
+  securityTrustProxy: Boolean!
   securityHSTS: Boolean!
   securityHSTSDuration: Int!
   securityCSP: Boolean!
diff --git a/server/master.js b/server/master.js
index 1a9af010..ff4a6b36 100644
--- a/server/master.js
+++ b/server/master.js
@@ -48,7 +48,7 @@ module.exports = async () => {
   app.use(mw.security)
   app.use(cors(WIKI.config.cors))
   app.options('*', cors(WIKI.config.cors))
-  if (WIKI.config.trustProxy) {
+  if (WIKI.config.security.securityTrustProxy) {
     app.enable('trust proxy')
   }