Compare commits
	
		
			15 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					8403ac0e93 | ||
| 
						 | 
					c2f21b70dd | ||
| 
						 | 
					520145e0e3 | ||
| 
						 | 
					6a132187a2 | ||
| 
						 | 
					a63a9ccd76 | ||
| 
						 | 
					ff1eb791db | ||
| 
						 | 
					13bd88b979 | ||
| 
						 | 
					5b0c244920 | ||
| 
						 | 
					0318a17cac | ||
| 
						 | 
					b7a91563b0 | ||
| 
						 | 
					75296ed8ee | ||
| 
						 | 
					09bee45b2f | ||
| 
						 | 
					3573c48872 | ||
| 
						 | 
					784841c221 | ||
| 
						 | 
					ed788a1861 | 
							
								
								
									
										2
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							@@ -5,7 +5,7 @@
 | 
			
		||||
    "esbenp.prettier-vscode",
 | 
			
		||||
    "editorconfig.editorconfig",
 | 
			
		||||
    "vue.volar",
 | 
			
		||||
    "wayou.vscode-todo-highlight",
 | 
			
		||||
    "wayou.vscode-todo-highlight"
 | 
			
		||||
  ],
 | 
			
		||||
  "unwantedRecommendations": [
 | 
			
		||||
    "octref.vetur",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@@ -4,16 +4,9 @@
 | 
			
		||||
  "editor.formatOnSave": true,
 | 
			
		||||
  "[vue][javascript][typescript][javascriptreact]": {
 | 
			
		||||
    "editor.defaultFormatter": "esbenp.prettier-vscode",
 | 
			
		||||
    "editor.codeActionsOnSave": [
 | 
			
		||||
      "source.fixAll.eslint"
 | 
			
		||||
    ],
 | 
			
		||||
    "editor.codeActionsOnSave": ["source.fixAll.eslint"]
 | 
			
		||||
  },
 | 
			
		||||
  "eslint.validate": [
 | 
			
		||||
    "javascript",
 | 
			
		||||
    "javascriptreact",
 | 
			
		||||
    "typescript",
 | 
			
		||||
    "vue"
 | 
			
		||||
  ],
 | 
			
		||||
  "eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"],
 | 
			
		||||
  "typescript.tsdk": "node_modules/typescript/lib",
 | 
			
		||||
  "files.watcherExclude": {
 | 
			
		||||
    "files.watcherExclude": {
 | 
			
		||||
@@ -22,7 +15,7 @@
 | 
			
		||||
      "**/node_modules/": true,
 | 
			
		||||
      "/node_modules/**": true,
 | 
			
		||||
      "**/env/": true,
 | 
			
		||||
      "/env/**": true,
 | 
			
		||||
      "/env/**": true
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								index.html
									
									
									
									
									
								
							@@ -1,24 +1,22 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <title><%= productName %></title>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
  <title>
 | 
			
		||||
    <%= productName %>
 | 
			
		||||
  </title>
 | 
			
		||||
 | 
			
		||||
  <meta charset="utf-8" />
 | 
			
		||||
  <meta name="robots" content="noindex" />
 | 
			
		||||
  <meta name="description" content="<%= productDescription %>" />
 | 
			
		||||
  <meta name="format-detection" content="telephone=no" />
 | 
			
		||||
  <meta name="msapplication-tap-highlight" content="no" />
 | 
			
		||||
  <meta name="viewport"
 | 
			
		||||
    content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>" />
 | 
			
		||||
  <link rel="icon" type="image/ico" href="favicon.ico" />
 | 
			
		||||
  <script src="/env-config.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
  <!-- quasar:entry-point -->
 | 
			
		||||
</body>
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
    <meta name="robots" content="noindex" />
 | 
			
		||||
    <meta name="description" content="<%= productDescription %>" />
 | 
			
		||||
    <meta name="format-detection" content="telephone=no" />
 | 
			
		||||
    <meta name="msapplication-tap-highlight" content="no" />
 | 
			
		||||
    <meta
 | 
			
		||||
      name="viewport"
 | 
			
		||||
      content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"
 | 
			
		||||
    />
 | 
			
		||||
    <link rel="icon" type="image/ico" href="favicon.ico" />
 | 
			
		||||
    <script src="/env-config.js"></script>
 | 
			
		||||
  </head>
 | 
			
		||||
 | 
			
		||||
  <body>
 | 
			
		||||
    <!-- quasar:entry-point -->
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6027
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6027
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										36
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								package.json
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "web",
 | 
			
		||||
  "version": "0.101.11",
 | 
			
		||||
  "version": "0.101.16",
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "productName": "Tactical RMM",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
@@ -10,13 +10,13 @@
 | 
			
		||||
    "format": "prettier --write \"**/*.{js,ts,vue,,html,md,json}\" --ignore-path .gitignore"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@quasar/extras": "1.15.8",
 | 
			
		||||
    "apexcharts": "3.36.3",
 | 
			
		||||
    "axios": "0.27.2",
 | 
			
		||||
    "@quasar/extras": "1.15.11",
 | 
			
		||||
    "apexcharts": "3.37.1",
 | 
			
		||||
    "axios": "1.3.4",
 | 
			
		||||
    "dotenv": "16.0.3",
 | 
			
		||||
    "qrcode.vue": "3.3.3",
 | 
			
		||||
    "quasar": "2.11.1",
 | 
			
		||||
    "vue": "3.2.45",
 | 
			
		||||
    "qrcode.vue": "3.3.4",
 | 
			
		||||
    "quasar": "2.11.8",
 | 
			
		||||
    "vue": "3.2.47",
 | 
			
		||||
    "vue3-ace-editor": "2.2.2",
 | 
			
		||||
    "vue3-apexcharts": "1.4.1",
 | 
			
		||||
    "vuedraggable": "4.1.0",
 | 
			
		||||
@@ -24,17 +24,17 @@
 | 
			
		||||
    "vuex": "4.1.0"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@quasar/cli": "^1.3.2",
 | 
			
		||||
    "@intlify/vite-plugin-vue-i18n": "^6.0.3",
 | 
			
		||||
    "@quasar/app-vite": "^1.1.3",
 | 
			
		||||
    "@types/node": "^18.11.17",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^5.47.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^5.47.0",
 | 
			
		||||
    "autoprefixer": "10.4.13",
 | 
			
		||||
    "eslint": "8.30.0",
 | 
			
		||||
    "eslint-config-prettier": "8.5.0",
 | 
			
		||||
    "@quasar/cli": "^2.0.0",
 | 
			
		||||
    "@intlify/unplugin-vue-i18n": "^0.9.2",
 | 
			
		||||
    "@quasar/app-vite": "^1.2.1",
 | 
			
		||||
    "@types/node": "^18.15.3",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^5.55.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^5.55.0",
 | 
			
		||||
    "autoprefixer": "10.4.14",
 | 
			
		||||
    "eslint": "8.36.0",
 | 
			
		||||
    "eslint-config-prettier": "8.7.0",
 | 
			
		||||
    "eslint-plugin-vue": "8.7.1",
 | 
			
		||||
    "prettier": "2.8.1",
 | 
			
		||||
    "typescript": "4.9.4"
 | 
			
		||||
    "prettier": "2.8.4",
 | 
			
		||||
    "typescript": "4.9.5"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -4,18 +4,18 @@
 | 
			
		||||
module.exports = {
 | 
			
		||||
  plugins: [
 | 
			
		||||
    // https://github.com/postcss/autoprefixer
 | 
			
		||||
    require('autoprefixer')({
 | 
			
		||||
    require("autoprefixer")({
 | 
			
		||||
      overrideBrowserslist: [
 | 
			
		||||
        'last 4 Chrome versions',
 | 
			
		||||
        'last 4 Firefox versions',
 | 
			
		||||
        'last 4 Edge versions',
 | 
			
		||||
        'last 4 Safari versions',
 | 
			
		||||
        'last 4 Android versions',
 | 
			
		||||
        'last 4 ChromeAndroid versions',
 | 
			
		||||
        'last 4 FirefoxAndroid versions',
 | 
			
		||||
        'last 4 iOS versions'
 | 
			
		||||
      ]
 | 
			
		||||
    })
 | 
			
		||||
        "last 4 Chrome versions",
 | 
			
		||||
        "last 4 Firefox versions",
 | 
			
		||||
        "last 4 Edge versions",
 | 
			
		||||
        "last 4 Safari versions",
 | 
			
		||||
        "last 4 Android versions",
 | 
			
		||||
        "last 4 ChromeAndroid versions",
 | 
			
		||||
        "last 4 FirefoxAndroid versions",
 | 
			
		||||
        "last 4 iOS versions",
 | 
			
		||||
      ],
 | 
			
		||||
    }),
 | 
			
		||||
 | 
			
		||||
    // https://github.com/elchininet/postcss-rtlcss
 | 
			
		||||
    // If you want to support RTL css, then
 | 
			
		||||
@@ -23,5 +23,5 @@ module.exports = {
 | 
			
		||||
    // 2. optionally set quasar.config.js > framework > lang to an RTL language
 | 
			
		||||
    // 3. uncomment the following line:
 | 
			
		||||
    // require('postcss-rtlcss')
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
  ],
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -374,16 +374,10 @@ export default {
 | 
			
		||||
        "make_model",
 | 
			
		||||
        "physical_disks",
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      // quasar filter only does visible columns so this is a hack to add hidden columns we want to filter
 | 
			
		||||
      for (const elem of hiddenFields) {
 | 
			
		||||
        if (!cols.find((o) => o.name === elem)) {
 | 
			
		||||
          cols.push({
 | 
			
		||||
            name: elem,
 | 
			
		||||
            field: elem,
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // originally I was modifying cols directly but this led to phantom colum so doing it this way now
 | 
			
		||||
      // https://github.com/amidaware/tacticalrmm/issues/1264
 | 
			
		||||
      const allColumns = [...cols, ...hiddenFields.map((field) => ({ field }))];
 | 
			
		||||
 | 
			
		||||
      const lowerTerms = terms ? terms.toLowerCase() : "";
 | 
			
		||||
      let advancedFilter = false;
 | 
			
		||||
@@ -437,7 +431,7 @@ export default {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Normal text filter
 | 
			
		||||
        return cols.some((col) => {
 | 
			
		||||
        return allColumns.some((col) => {
 | 
			
		||||
          const val = cellValue(col, row) + "";
 | 
			
		||||
          const haystack =
 | 
			
		||||
            val === "undefined" || val === "null" ? "" : val.toLowerCase();
 | 
			
		||||
 
 | 
			
		||||
@@ -166,7 +166,7 @@ export default {
 | 
			
		||||
          type: "textarea",
 | 
			
		||||
          isValid: (val) => !!val,
 | 
			
		||||
        },
 | 
			
		||||
        style: "width: 30vw; max-width: 50vw;",
 | 
			
		||||
        style: "width: 90vw; max-width: 90vw",
 | 
			
		||||
        ok: { label: "Add" },
 | 
			
		||||
        cancel: true,
 | 
			
		||||
      }).onOk(async () => {
 | 
			
		||||
@@ -193,7 +193,7 @@ export default {
 | 
			
		||||
          type: "textarea",
 | 
			
		||||
          isValid: (val) => !!val,
 | 
			
		||||
        },
 | 
			
		||||
        style: "width: 30vw; max-width: 50vw;",
 | 
			
		||||
        style: "width: 90vw; max-width: 90vw",
 | 
			
		||||
        ok: { label: "Save" },
 | 
			
		||||
        cancel: true,
 | 
			
		||||
      }).onOk(async (data) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,16 +8,16 @@
 | 
			
		||||
            v
 | 
			
		||||
          }}</q-badge>
 | 
			
		||||
          <q-btn
 | 
			
		||||
              v-if="!!v"
 | 
			
		||||
              size="sm"
 | 
			
		||||
              class="q-ml-xs"
 | 
			
		||||
              flat
 | 
			
		||||
              round
 | 
			
		||||
              icon="content_copy"
 | 
			
		||||
              @click="copyValueToClip(v)"
 | 
			
		||||
            >
 | 
			
		||||
              <q-tooltip>Copy to Clipboard</q-tooltip>
 | 
			
		||||
            </q-btn>
 | 
			
		||||
            v-if="!!v"
 | 
			
		||||
            size="sm"
 | 
			
		||||
            class="q-ml-xs"
 | 
			
		||||
            flat
 | 
			
		||||
            round
 | 
			
		||||
            icon="content_copy"
 | 
			
		||||
            @click="copyValueToClip(v)"
 | 
			
		||||
          >
 | 
			
		||||
            <q-tooltip>Copy to Clipboard</q-tooltip>
 | 
			
		||||
          </q-btn>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <q-separator v-if="info.length > 1" />
 | 
			
		||||
@@ -42,10 +42,9 @@ export default {
 | 
			
		||||
    const tabHeight = computed(() => store.state.tabHeight);
 | 
			
		||||
 | 
			
		||||
    function copyValueToClip(val) {
 | 
			
		||||
      copyToClipboard(val)
 | 
			
		||||
        .then(() => {
 | 
			
		||||
          notifySuccess("Copied to clipboard");
 | 
			
		||||
        })
 | 
			
		||||
      copyToClipboard(val).then(() => {
 | 
			
		||||
        notifySuccess("Copied to clipboard");
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
 
 | 
			
		||||
@@ -128,7 +128,7 @@ import { useDialogPluginComponent } from "quasar";
 | 
			
		||||
import { useCheckModal } from "@/composables/checks";
 | 
			
		||||
import { useScriptDropdown } from "@/composables/scripts";
 | 
			
		||||
import { validateRetcode } from "@/utils/validation";
 | 
			
		||||
import { envVarsLabel } from "@/constants/constants"
 | 
			
		||||
import { envVarsLabel } from "@/constants/constants";
 | 
			
		||||
 | 
			
		||||
// ui imports
 | 
			
		||||
import TacticalDropdown from "@/components/ui/TacticalDropdown.vue";
 | 
			
		||||
@@ -146,10 +146,15 @@ export default {
 | 
			
		||||
    const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
 | 
			
		||||
 | 
			
		||||
    // setup script dropdown
 | 
			
		||||
    const { script, scriptOptions, defaultTimeout, defaultArgs, defaultEnvVars } =
 | 
			
		||||
      useScriptDropdown(props.check ? props.check.script : undefined, {
 | 
			
		||||
        onMount: true,
 | 
			
		||||
      });
 | 
			
		||||
    const {
 | 
			
		||||
      script,
 | 
			
		||||
      scriptOptions,
 | 
			
		||||
      defaultTimeout,
 | 
			
		||||
      defaultArgs,
 | 
			
		||||
      defaultEnvVars,
 | 
			
		||||
    } = useScriptDropdown(props.check ? props.check.script : undefined, {
 | 
			
		||||
      onMount: true,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // check logic
 | 
			
		||||
    const { state, loading, submit, failOptions, severityOptions } =
 | 
			
		||||
 
 | 
			
		||||
@@ -89,7 +89,8 @@
 | 
			
		||||
      <p class="text-italic">
 | 
			
		||||
        Note: the auth token above will be valid for {{ info.expires }} hours.
 | 
			
		||||
      </p>
 | 
			
		||||
      <q-btn v-if="info.plat === 'windows'"
 | 
			
		||||
      <q-btn
 | 
			
		||||
        v-if="info.plat === 'windows'"
 | 
			
		||||
        type="a"
 | 
			
		||||
        :href="info.data.url"
 | 
			
		||||
        color="primary"
 | 
			
		||||
 
 | 
			
		||||
@@ -221,11 +221,18 @@ export default {
 | 
			
		||||
    const { dialogRef, onDialogHide } = useDialogPluginComponent();
 | 
			
		||||
 | 
			
		||||
    // setup dropdowns
 | 
			
		||||
    const { script, scriptOptions, defaultTimeout, defaultArgs, defaultEnvVars, syntax, link } =
 | 
			
		||||
      useScriptDropdown(props.script, {
 | 
			
		||||
        onMount: true,
 | 
			
		||||
        filterByPlatform: props.agent.plat,
 | 
			
		||||
      });
 | 
			
		||||
    const {
 | 
			
		||||
      script,
 | 
			
		||||
      scriptOptions,
 | 
			
		||||
      defaultTimeout,
 | 
			
		||||
      defaultArgs,
 | 
			
		||||
      defaultEnvVars,
 | 
			
		||||
      syntax,
 | 
			
		||||
      link,
 | 
			
		||||
    } = useScriptDropdown(props.script, {
 | 
			
		||||
      onMount: true,
 | 
			
		||||
      filterByPlatform: props.agent.plat,
 | 
			
		||||
    });
 | 
			
		||||
    const { customFieldOptions } = useCustomFieldDropdown({ onMount: true });
 | 
			
		||||
 | 
			
		||||
    // main run script functionaity
 | 
			
		||||
 
 | 
			
		||||
@@ -836,10 +836,15 @@ export default {
 | 
			
		||||
    const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
 | 
			
		||||
 | 
			
		||||
    // setup dropdowns
 | 
			
		||||
    const { script, scriptOptions, defaultTimeout, defaultArgs, defaultEnvVars } =
 | 
			
		||||
      useScriptDropdown(undefined, {
 | 
			
		||||
        onMount: true,
 | 
			
		||||
      });
 | 
			
		||||
    const {
 | 
			
		||||
      script,
 | 
			
		||||
      scriptOptions,
 | 
			
		||||
      defaultTimeout,
 | 
			
		||||
      defaultArgs,
 | 
			
		||||
      defaultEnvVars,
 | 
			
		||||
    } = useScriptDropdown(undefined, {
 | 
			
		||||
      onMount: true,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // set defaultTimeout to 30
 | 
			
		||||
    defaultTimeout.value = 30;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ export function useScriptDropdown(setScript = null, { onMount = false } = {}) {
 | 
			
		||||
      );
 | 
			
		||||
      defaultTimeout.value = tmpScript.timeout;
 | 
			
		||||
      defaultArgs.value = tmpScript.args;
 | 
			
		||||
      defaultEnvVars.value = tmpScript.env_vars,
 | 
			
		||||
      defaultEnvVars.value = tmpScript.env_vars;
 | 
			
		||||
      syntax.value = tmpScript.syntax;
 | 
			
		||||
      link.value =
 | 
			
		||||
        tmpScript.script_type === "builtin"
 | 
			
		||||
 
 | 
			
		||||
@@ -7,4 +7,4 @@ export const runAsUserToolTip =
 | 
			
		||||
  "Run in the context of the logged in user. If no user is logged in, the script will not run and an error will be returned.";
 | 
			
		||||
 | 
			
		||||
export const envVarsLabel =
 | 
			
		||||
  "Environment vars (press Enter after typing each key=value pair)"
 | 
			
		||||
  "Environment vars (press Enter after typing each key=value pair)";
 | 
			
		||||
 
 | 
			
		||||
@@ -173,6 +173,18 @@
 | 
			
		||||
                        </q-menu>
 | 
			
		||||
                      </q-item>
 | 
			
		||||
 | 
			
		||||
                      <!-- Bulk Run Checks -->
 | 
			
		||||
                      <q-item
 | 
			
		||||
                        clickable
 | 
			
		||||
                        v-close-popup
 | 
			
		||||
                        @click="runChecks(props.node)"
 | 
			
		||||
                      >
 | 
			
		||||
                        <q-item-section side>
 | 
			
		||||
                          <q-icon name="fas fa-check-double" />
 | 
			
		||||
                        </q-item-section>
 | 
			
		||||
                        <q-item-section>Run Checks</q-item-section>
 | 
			
		||||
                      </q-item>
 | 
			
		||||
 | 
			
		||||
                      <q-separator></q-separator>
 | 
			
		||||
 | 
			
		||||
                      <q-item clickable v-close-popup>
 | 
			
		||||
@@ -690,6 +702,17 @@ export default {
 | 
			
		||||
        })
 | 
			
		||||
        .onOk(() => this.$store.dispatch("refreshDashboard"));
 | 
			
		||||
    },
 | 
			
		||||
    runChecks(node) {
 | 
			
		||||
      const target = node.children ? "client" : "site";
 | 
			
		||||
      this.$axios
 | 
			
		||||
        .post(`/checks/${target}/${node.id}/csbulkrun/`)
 | 
			
		||||
        .then((r) => {
 | 
			
		||||
          this.notifySuccess(r.data);
 | 
			
		||||
        })
 | 
			
		||||
        .catch((e) => {
 | 
			
		||||
          console.error(e);
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
    showToggleMaintenance(node) {
 | 
			
		||||
      let data = {
 | 
			
		||||
        id: node.id,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user