mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-28 10:18:51 +00:00
Merge pull request #443 from firezone/backlog/261/password_strength_requirements
Increase password length requirements to 12
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import hljs from "highlight.js"
|
||||
import {FormatTimestamp} from "./util.js"
|
||||
import {FormatTimestamp,PasswordStrength} from "./util.js"
|
||||
import {renderQrCode} from "./qrcode.js"
|
||||
|
||||
const highlightCode = function () {
|
||||
@@ -11,6 +11,46 @@ const formatTimestamp = function () {
|
||||
this.el.innerHTML = FormatTimestamp(t)
|
||||
}
|
||||
|
||||
const passwordStrength = function () {
|
||||
const field = this.el
|
||||
const fieldClasses = "password input "
|
||||
const progress = document.getElementById(field.dataset.target)
|
||||
const reset = function () {
|
||||
field.className = fieldClasses
|
||||
progress.className = "is-hidden"
|
||||
progress.setAttribute("value", "0")
|
||||
progress.innerHTML = "0%"
|
||||
}
|
||||
field.addEventListener("input", () => {
|
||||
if (field.value === "") return reset()
|
||||
const score = PasswordStrength(field.value)
|
||||
switch (score) {
|
||||
case 0:
|
||||
case 1:
|
||||
field.className = fieldClasses + "is-danger"
|
||||
progress.className = "progress is-small is-danger"
|
||||
progress.setAttribute("value", "33")
|
||||
progress.innerHTML = "33%"
|
||||
break
|
||||
case 2:
|
||||
case 3:
|
||||
field.className = fieldClasses + "is-warning"
|
||||
progress.className = "progress is-small is-warning"
|
||||
progress.setAttribute("value", "67")
|
||||
progress.innerHTML = "67%"
|
||||
break
|
||||
case 4:
|
||||
field.className = fieldClasses + "is-success"
|
||||
progress.className = "progress is-small is-success"
|
||||
progress.setAttribute("value", "100")
|
||||
progress.innerHTML = "100%"
|
||||
break
|
||||
default:
|
||||
reset()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const clipboardCopy = function () {
|
||||
let button = this.el
|
||||
let data = button.dataset.clipboard
|
||||
@@ -37,5 +77,9 @@ Hooks.FormatTimestamp = {
|
||||
mounted: formatTimestamp,
|
||||
updated: formatTimestamp
|
||||
}
|
||||
Hooks.PasswordStrength = {
|
||||
mounted: passwordStrength,
|
||||
updated: passwordStrength
|
||||
}
|
||||
|
||||
export default Hooks
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import moment from "moment"
|
||||
import zxcvbn from "zxcvbn"
|
||||
|
||||
const FormatTimestamp = function (timestamp) {
|
||||
if (timestamp) {
|
||||
@@ -8,4 +9,9 @@ const FormatTimestamp = function (timestamp) {
|
||||
}
|
||||
}
|
||||
|
||||
export { FormatTimestamp }
|
||||
const PasswordStrength = function (password) {
|
||||
const result = zxcvbn(password)
|
||||
return result.score
|
||||
}
|
||||
|
||||
export { PasswordStrength, FormatTimestamp }
|
||||
|
||||
15
apps/fz_http/assets/package-lock.json
generated
15
apps/fz_http/assets/package-lock.json
generated
@@ -43,7 +43,8 @@
|
||||
"source-map": "^0.7.3",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "5.36.0",
|
||||
"webpack-cli": "^4.9.2"
|
||||
"webpack-cli": "^4.9.2",
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.0.0"
|
||||
@@ -8061,6 +8062,12 @@
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zxcvbn": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
|
||||
"integrity": "sha1-KOwXzwl0PtyrBW3dixsGJizHPDA=",
|
||||
"dev": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -13904,6 +13911,12 @@
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"zxcvbn": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
|
||||
"integrity": "sha1-KOwXzwl0PtyrBW3dixsGJizHPDA=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
"source-map": "^0.7.3",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "5.36.0",
|
||||
"webpack-cli": "^4.9.2"
|
||||
"webpack-cli": "^4.9.2",
|
||||
"zxcvbn": "^4.4.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ defmodule FzHttp.Users.User do
|
||||
Represents a User.
|
||||
"""
|
||||
|
||||
@min_password_length 8
|
||||
@min_password_length 12
|
||||
@max_password_length 64
|
||||
|
||||
use Ecto.Schema
|
||||
@@ -173,4 +173,6 @@ defmodule FzHttp.Users.User do
|
||||
{:error, error_msg} -> changeset |> add_error(:current_password, error_msg)
|
||||
end
|
||||
end
|
||||
|
||||
defp verify_current_password(changeset, _user), do: changeset
|
||||
end
|
||||
|
||||
@@ -29,6 +29,19 @@ defmodule FzHttpWeb.ErrorHelpers do
|
||||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Adds "is-danger" to input elements that have errors
|
||||
"""
|
||||
def input_error_class(form, field) do
|
||||
case Keyword.get_values(form.errors, field) do
|
||||
[] ->
|
||||
""
|
||||
|
||||
_ ->
|
||||
"is-danger"
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Translates an error message using gettext.
|
||||
"""
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="field">
|
||||
<%= label f, :name, class: "label" %>
|
||||
<div class="control">
|
||||
<%= text_input f, :name, class: "input" %>
|
||||
<%= text_input f, :name, class: "input #{input_error_class(f, :name)}" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :name %>
|
||||
@@ -30,7 +30,8 @@
|
||||
<div class="field">
|
||||
<%= label f, :allowed_ips, "Allowed IPs", class: "label" %>
|
||||
<div class="control">
|
||||
<%= text_input f, :allowed_ips, class: "input", disabled: @use_default_allowed_ips %>
|
||||
<%= text_input f, :allowed_ips, class: "input #{input_error_class(f, :allowed_ips)}",
|
||||
disabled: @use_default_allowed_ips %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :allowed_ips %>
|
||||
@@ -57,7 +58,8 @@
|
||||
<div class="field">
|
||||
<%= label f, :dns, "DNS Servers", class: "label" %>
|
||||
<div class="control">
|
||||
<%= text_input f, :dns, class: "input", disabled: @use_default_dns %>
|
||||
<%= text_input f, :dns, class: "input #{input_error_class(f, :dns)}",
|
||||
disabled: @use_default_dns %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :dns %>
|
||||
@@ -85,7 +87,8 @@
|
||||
<%= label f, :endpoint, "Server Endpoint", class: "label" %>
|
||||
<p>The IP of the server this device should connect to.</p>
|
||||
<div class="control">
|
||||
<%= text_input f, :endpoint, class: "input", disabled: @use_default_endpoint %>
|
||||
<%= text_input f, :endpoint, class: "input #{input_error_class(f, :endpoint)}",
|
||||
disabled: @use_default_endpoint %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :endpoint %>
|
||||
@@ -113,7 +116,7 @@
|
||||
<%= label f, :mtu, "Interface MTU", class: "label" %>
|
||||
<p>The WireGuard interface MTU for this Device.</p>
|
||||
<div class="contro">
|
||||
<%= text_input f, :mtu, class: "input", disabled: @use_default_mtu %>
|
||||
<%= text_input f, :mtu, class: "input #{input_error_class(f, :mtu)}", disabled: @use_default_mtu %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :mtu %>
|
||||
@@ -146,7 +149,8 @@
|
||||
unless you're experiencing NAT or firewall traversal problems.
|
||||
</p>
|
||||
<div class="control">
|
||||
<%= text_input f, :persistent_keepalive, class: "input", disabled: @use_default_persistent_keepalive %>
|
||||
<%= text_input f, :persistent_keepalive, class: "input #{input_error_class(f, :persistent_keepalive)}",
|
||||
disabled: @use_default_persistent_keepalive %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :persistent_keepalive %>
|
||||
@@ -157,7 +161,7 @@
|
||||
<%= label f, :ipv4, "IPv4 Address", class: "label" %>
|
||||
|
||||
<div class="control">
|
||||
<%= text_input f, :ipv4, class: "input" %>
|
||||
<%= text_input f, :ipv4, class: "input #{input_error_class(f, :ipv4)}" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :ipv4 %>
|
||||
@@ -168,7 +172,7 @@
|
||||
<%= label f, :ipv6, "IPv6 Address", class: "label" %>
|
||||
|
||||
<div class="control">
|
||||
<%= text_input f, :ipv6, class: "input" %>
|
||||
<%= text_input f, :ipv6, class: "input #{input_error_class(f, :ipv6)}" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :ipv6 %>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="control is-expanded">
|
||||
<%= text_input f,
|
||||
:destination,
|
||||
class: "input",
|
||||
class: "input #{input_error_class(f, :destination)}",
|
||||
placeholder: "IPv4/6 CIDR range or address" %>
|
||||
</div>
|
||||
<div class="control">
|
||||
|
||||
@@ -8,32 +8,24 @@
|
||||
<%= label f, :email, class: "label" %>
|
||||
|
||||
<div class="control">
|
||||
<%= text_input f, :email, class: "input" %>
|
||||
<%= text_input f, :email, class: "input #{input_error_class(f, :email)}" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :email %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= label f, :password, "New password", class: "label" %>
|
||||
<div class="control">
|
||||
<%= password_input f, :password, class: "input password" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :password %>
|
||||
</p>
|
||||
</div>
|
||||
<%= render FzHttpWeb.SharedView,
|
||||
"password_field.html",
|
||||
context: f,
|
||||
field: :password,
|
||||
label: "Password" %>
|
||||
|
||||
<div class="field">
|
||||
<%= label f, :password_confirmation, "New password confirmation", class: "label" %>
|
||||
<div class="control">
|
||||
<%= password_input f, :password_confirmation, class: "input password" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :password_confirmation %>
|
||||
</p>
|
||||
</div>
|
||||
<%= render FzHttpWeb.SharedView,
|
||||
"password_field.html",
|
||||
context: f,
|
||||
field: :password_confirmation,
|
||||
label: "Password Confirmation" %>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
@@ -10,34 +10,24 @@
|
||||
<%= label f, :email, class: "label" %>
|
||||
|
||||
<div class="control">
|
||||
<%= text_input f, :email, class: "input" %>
|
||||
<%= text_input f, :email, class: "input #{input_error_class(f, :email)}" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :email %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= label f, :password, "New Password", class: "label" %>
|
||||
<%= render FzHttpWeb.SharedView,
|
||||
"password_field.html",
|
||||
context: f,
|
||||
field: :password,
|
||||
label: "New Password" %>
|
||||
|
||||
<div class="control">
|
||||
<%= password_input f, :password, class: "input password" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :password %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= label f, :password_confirmation, "New Password Confirmation", class: "label" %>
|
||||
|
||||
<div class="control">
|
||||
<%= password_input f, :password_confirmation, class: "input password" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :password_confirmation %>
|
||||
</p>
|
||||
</div>
|
||||
<%= render FzHttpWeb.SharedView,
|
||||
"password_field.html",
|
||||
context: f,
|
||||
field: :password_confirmation,
|
||||
label: "New Password Confirmation" %>
|
||||
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<!-- Use https://admin-one.justboil.me/?style=light-dark#/lock-screen for inspiration -->
|
||||
<h3 class="is-3 title">Sign In</h3>
|
||||
|
||||
<hr>
|
||||
@@ -13,7 +12,7 @@
|
||||
<div class="field">
|
||||
<%= label(:session, :email, class: "label") %>
|
||||
<div class="control">
|
||||
<%= text_input(f, :email, class: "input") %>
|
||||
<%= text_input(f, :email, class: "input #{input_error_class(f, :email)}") %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :email %>
|
||||
@@ -23,7 +22,7 @@
|
||||
<div class="field">
|
||||
<%= label(:session, :password, class: "label") %>
|
||||
<div class="control">
|
||||
<%= password_input(f, :password, class: "input") %>
|
||||
<%= password_input(f, :password, class: "input #{input_error_class(f, :password)}") %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag f, :password %>
|
||||
@@ -0,0 +1,21 @@
|
||||
<div class="field">
|
||||
<%= label @context, @field, @label, class: "label" %>
|
||||
|
||||
<div class="control">
|
||||
<%= password_input @context,
|
||||
@field,
|
||||
class: "input password",
|
||||
id: "#{@field}-field",
|
||||
data_target: "#{@field}-progress",
|
||||
phx_hook: "PasswordStrength" %>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
<%= error_tag @context, @field %>
|
||||
</p>
|
||||
|
||||
<progress
|
||||
id={"#{@field}-progress"}
|
||||
class="is-hidden"
|
||||
value="0"
|
||||
max="100">0%</progress>
|
||||
</div>
|
||||
@@ -31,7 +31,7 @@ defmodule FzHttp.ReleaseTest do
|
||||
|
||||
test "reset admin password when user exists" do
|
||||
{:ok, first_user} = Release.create_admin_user()
|
||||
{:ok, new_first_user} = Release.change_password(first_user.email, "newpassword")
|
||||
{:ok, new_first_user} = Release.change_password(first_user.email, "newpassword1234")
|
||||
{:ok, second_user} = Release.create_admin_user()
|
||||
|
||||
assert second_user.password_hash != new_first_user.password_hash
|
||||
|
||||
@@ -36,7 +36,7 @@ defmodule FzHttp.SessionsTest do
|
||||
describe "create_session/2" do
|
||||
setup [:create_user]
|
||||
|
||||
@password_params %{password: "testtest"}
|
||||
@password_params %{password: "password1234"}
|
||||
@invalid_params %{password: "invalid"}
|
||||
|
||||
test "creates session (updates existing record)", %{user: user} do
|
||||
|
||||
@@ -61,23 +61,23 @@ defmodule FzHttp.UsersTest do
|
||||
describe "create_user/1" do
|
||||
@valid_attrs_map %{
|
||||
email: "valid@test",
|
||||
password: "password",
|
||||
password_confirmation: "password"
|
||||
password: "password1234",
|
||||
password_confirmation: "password1234"
|
||||
}
|
||||
@valid_attrs_list [
|
||||
email: "valid@test",
|
||||
password: "password",
|
||||
password_confirmation: "password"
|
||||
password: "password1234",
|
||||
password_confirmation: "password1234"
|
||||
]
|
||||
@invalid_attrs_map %{
|
||||
email: "invalid_email",
|
||||
password: "password",
|
||||
password_confirmation: "password"
|
||||
password: "password1234",
|
||||
password_confirmation: "password1234"
|
||||
}
|
||||
@invalid_attrs_list [
|
||||
email: "valid@test",
|
||||
password: "password",
|
||||
password_confirmation: "different_password"
|
||||
password: "password1234",
|
||||
password_confirmation: "different_password1234"
|
||||
]
|
||||
@too_short_password [
|
||||
email: "valid@test",
|
||||
@@ -95,7 +95,7 @@ defmodule FzHttp.UsersTest do
|
||||
|
||||
assert changeset.errors[:password] == {
|
||||
"should be at least %{count} character(s)",
|
||||
[count: 8, validation: :length, kind: :min, type: :string]
|
||||
[count: 12, validation: :length, kind: :min, type: :string]
|
||||
}
|
||||
end
|
||||
|
||||
@@ -140,7 +140,7 @@ defmodule FzHttp.UsersTest do
|
||||
@change_password_valid_params %{
|
||||
"password" => "new_password",
|
||||
"password_confirmation" => "new_password",
|
||||
"current_password" => "testtest"
|
||||
"current_password" => "password1234"
|
||||
}
|
||||
@change_password_invalid_params %{
|
||||
"password" => "new_password",
|
||||
|
||||
@@ -54,7 +54,7 @@ defmodule FzHttpWeb.SessionControllerTest do
|
||||
params = %{
|
||||
"session" => %{
|
||||
"email" => user.email,
|
||||
"password" => "testtest"
|
||||
"password" => "password1234"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ defmodule FzHttpWeb.DeviceLive.ShowTest do
|
||||
|> render_change(@default_allowed_ips_change)
|
||||
|
||||
assert test_view =~ """
|
||||
<input class="input" id="edit-device_allowed_ips" name="device[allowed_ips]" type="text"/>\
|
||||
<input class="input " id="edit-device_allowed_ips" name="device[allowed_ips]" type="text"/>\
|
||||
"""
|
||||
end
|
||||
|
||||
@@ -275,7 +275,7 @@ defmodule FzHttpWeb.DeviceLive.ShowTest do
|
||||
|> render_change(@default_dns_change)
|
||||
|
||||
assert test_view =~ """
|
||||
<input class="input" id="edit-device_dns" name="device[dns]" type="text"/>\
|
||||
<input class="input " id="edit-device_dns" name="device[dns]" type="text"/>\
|
||||
"""
|
||||
end
|
||||
|
||||
@@ -289,7 +289,7 @@ defmodule FzHttpWeb.DeviceLive.ShowTest do
|
||||
|> render_change(@default_endpoint_change)
|
||||
|
||||
assert test_view =~ """
|
||||
<input class="input" id="edit-device_endpoint" name="device[endpoint]" type="text"/>\
|
||||
<input class="input " id="edit-device_endpoint" name="device[endpoint]" type="text"/>\
|
||||
"""
|
||||
end
|
||||
|
||||
@@ -303,7 +303,7 @@ defmodule FzHttpWeb.DeviceLive.ShowTest do
|
||||
|> render_change(@default_mtu_change)
|
||||
|
||||
assert test_view =~ """
|
||||
<input class="input" id="edit-device_mtu" name="device[mtu]" type="text"/>\
|
||||
<input class="input " id="edit-device_mtu" name="device[mtu]" type="text"/>\
|
||||
"""
|
||||
end
|
||||
|
||||
@@ -317,7 +317,7 @@ defmodule FzHttpWeb.DeviceLive.ShowTest do
|
||||
|> render_change(@default_persistent_keepalive_change)
|
||||
|
||||
assert test_view =~ """
|
||||
<input class="input" id="edit-device_persistent_keepalive" name="device[persistent_keepalive]" type="text"/>\
|
||||
<input class="input " id="edit-device_persistent_keepalive" name="device[persistent_keepalive]" type="text"/>\
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
||||
@@ -98,7 +98,7 @@ defmodule FzHttpWeb.UserLive.IndexTest do
|
||||
|> render_submit(@invalid_user_attrs)
|
||||
|
||||
assert new_view =~ "has invalid format"
|
||||
assert new_view =~ "should be at least 8 character(s)"
|
||||
assert new_view =~ "should be at least 12 character(s)"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ defmodule FzHttpWeb.UserLive.ShowTest do
|
||||
|> render_submit(@invalid_attrs)
|
||||
|
||||
assert new_view =~ "has invalid format"
|
||||
assert new_view =~ "should be at least 8 character(s)"
|
||||
assert new_view =~ "should be at least 12 character(s)"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ defmodule FzHttp.SessionsFixtures do
|
||||
def session(_attrs \\ %{}) do
|
||||
email = UsersFixtures.user().email
|
||||
record = Sessions.get_session!(email: email)
|
||||
create_params = %{email: email, password: "testtest"}
|
||||
create_params = %{email: email, password: "password1234"}
|
||||
{:ok, session} = Sessions.create_session(record, create_params)
|
||||
session
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ defmodule FzHttp.UsersFixtures do
|
||||
case Repo.get_by(User, email: email) do
|
||||
nil ->
|
||||
{:ok, user} =
|
||||
%{email: email, password: "testtest", password_confirmation: "testtest"}
|
||||
%{email: email, password: "password1234", password_confirmation: "password1234"}
|
||||
|> Map.merge(attrs)
|
||||
|> Users.create_admin_user()
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ config :fz_http,
|
||||
cookie_signing_salt: "Z9eq8iof",
|
||||
ecto_repos: [FzHttp.Repo],
|
||||
admin_email: "firezone@localhost",
|
||||
default_admin_password: "firezone",
|
||||
default_admin_password: "firezone1234",
|
||||
events_module: FzHttpWeb.Events,
|
||||
server_process_opts: [name: {:global, :fz_http_server}]
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ class Firezone
|
||||
'database_encryption_key' => node['firezone'] && node['firezone']['database_encryption_key'] || \
|
||||
SecureRandom.base64(32),
|
||||
'default_admin_password' => node['firezone'] && node['firezone']['default_admin_password'] || \
|
||||
SecureRandom.base64(8)
|
||||
SecureRandom.base64(12)
|
||||
}
|
||||
end
|
||||
# rubocop:enable Metrics/PerceivedComplexity
|
||||
|
||||
Reference in New Issue
Block a user