Compare commits
2 Commits
aab65e17b3
...
bf415d7a2e
Author | SHA1 | Date |
---|---|---|
Les De Ridder | bf415d7a2e | |
Les De Ridder | b2ede45d82 |
|
@ -7,9 +7,7 @@ AppDatabase.configure do |settings|
|
||||||
settings.url = ENV["DATABASE_URL"]? || Avram::PostgresURL.build(
|
settings.url = ENV["DATABASE_URL"]? || Avram::PostgresURL.build(
|
||||||
database: database_name,
|
database: database_name,
|
||||||
hostname: ENV["DB_HOST"]? || "localhost",
|
hostname: ENV["DB_HOST"]? || "localhost",
|
||||||
# Some common usernames are "postgres", "root", or your system username (run 'whoami')
|
|
||||||
username: ENV["DB_USERNAME"]? || "postgres",
|
username: ENV["DB_USERNAME"]? || "postgres",
|
||||||
# Some Postgres installations require no password. Use "" if that is the case.
|
|
||||||
password: ENV["DB_PASSWORD"]? || "postgres"
|
password: ENV["DB_PASSWORD"]? || "postgres"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ class CreateUsers::V00000000000001 < Avram::Migrator::Migration::V1
|
||||||
|
|
||||||
add name : String, unique: true
|
add name : String, unique: true
|
||||||
add encrypted_password : String # NOTE: Should really be called 'password_hash'
|
add encrypted_password : String # NOTE: Should really be called 'password_hash'
|
||||||
add email : String?, unique: true
|
add email : String, unique: true # NOTE: Should be nilable, but Carbon::Emailable doesn't really support it
|
||||||
add created_at : Time
|
add created_at : Time
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
require "../spec_helper"
|
|
||||||
|
|
||||||
describe "Authentication flow" do
|
|
||||||
it "works" do
|
|
||||||
flow = AuthenticationFlow.new("test@example.com")
|
|
||||||
|
|
||||||
flow.sign_up "password"
|
|
||||||
flow.should_be_signed_in
|
|
||||||
flow.sign_out
|
|
||||||
flow.sign_in "wrong-password"
|
|
||||||
flow.should_have_password_error
|
|
||||||
flow.sign_in "password"
|
|
||||||
flow.should_be_signed_in
|
|
||||||
end
|
|
||||||
|
|
||||||
# This is to show you how to sign in as a user during tests.
|
|
||||||
# Use the `visit` method's `as` option in your tests to sign in as that user.
|
|
||||||
#
|
|
||||||
# Feel free to delete this once you have other tests using the 'as' option.
|
|
||||||
it "allows sign in through backdoor when testing" do
|
|
||||||
user = UserBox.create
|
|
||||||
flow = BaseFlow.new
|
|
||||||
|
|
||||||
flow.visit Me::Show, as: user
|
|
||||||
should_be_signed_in(flow)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private def should_be_signed_in(flow)
|
|
||||||
flow.el("@sign-out-button").should be_on_page
|
|
||||||
end
|
|
|
@ -1,18 +0,0 @@
|
||||||
require "../spec_helper"
|
|
||||||
|
|
||||||
describe "Reset password flow" do
|
|
||||||
it "works" do
|
|
||||||
user = UserBox.create
|
|
||||||
flow = ResetPasswordFlow.new(user)
|
|
||||||
|
|
||||||
flow.request_password_reset
|
|
||||||
flow.should_have_sent_reset_email
|
|
||||||
flow.reset_password "new-password"
|
|
||||||
flow.should_be_signed_in
|
|
||||||
flow.sign_out
|
|
||||||
flow.sign_in "wrong-password"
|
|
||||||
flow.should_have_password_error
|
|
||||||
flow.sign_in "new-password"
|
|
||||||
flow.should_be_signed_in
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,11 +1,11 @@
|
||||||
require "../../../spec_helper"
|
require "../../../spec_helper"
|
||||||
|
|
||||||
describe Api::SignIns::Create do
|
describe Api::SignIn::Create do
|
||||||
it "returns a token" do
|
it "returns a token" do
|
||||||
UserToken.stub_token("fake-token") do
|
UserToken.stub_token("fake-token") do
|
||||||
user = UserBox.create
|
user = UserBox.create
|
||||||
|
|
||||||
response = AppClient.exec(Api::SignIns::Create, user: valid_params(user))
|
response = AppClient.exec(Api::SignIn::Create, user: valid_params(user))
|
||||||
|
|
||||||
response.should send_json(200, token: "fake-token")
|
response.should send_json(200, token: "fake-token")
|
||||||
end
|
end
|
||||||
|
@ -15,7 +15,7 @@ describe Api::SignIns::Create do
|
||||||
user = UserBox.create
|
user = UserBox.create
|
||||||
invalid_params = valid_params(user).merge(password: "incorrect")
|
invalid_params = valid_params(user).merge(password: "incorrect")
|
||||||
|
|
||||||
response = AppClient.exec(Api::SignIns::Create, user: invalid_params)
|
response = AppClient.exec(Api::SignIn::Create, user: invalid_params)
|
||||||
|
|
||||||
response.should send_json(
|
response.should send_json(
|
||||||
400,
|
400,
|
||||||
|
@ -27,7 +27,7 @@ end
|
||||||
|
|
||||||
private def valid_params(user : User)
|
private def valid_params(user : User)
|
||||||
{
|
{
|
||||||
email: user.email,
|
name: user.name,
|
||||||
password: "password",
|
password: "password",
|
||||||
}
|
}
|
||||||
end
|
end
|
|
@ -1,12 +1,13 @@
|
||||||
require "../../../spec_helper"
|
require "../../../spec_helper"
|
||||||
|
|
||||||
describe Api::SignUps::Create do
|
describe Api::SignUp::Create do
|
||||||
it "creates user on sign up" do
|
it "creates user on sign up" do
|
||||||
UserToken.stub_token("fake-token") do
|
UserToken.stub_token("fake-token") do
|
||||||
response = AppClient.exec(Api::SignUps::Create, user: valid_params)
|
response = AppClient.exec(Api::SignUp::Create, user: valid_params)
|
||||||
|
|
||||||
response.should send_json(200, token: "fake-token")
|
response.should send_json(200, token: "fake-token")
|
||||||
new_user = UserQuery.first
|
new_user = UserQuery.first
|
||||||
|
new_user.name.should eq(valid_params[:name])
|
||||||
new_user.email.should eq(valid_params[:email])
|
new_user.email.should eq(valid_params[:email])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -14,7 +15,7 @@ describe Api::SignUps::Create do
|
||||||
it "returns error for invalid params" do
|
it "returns error for invalid params" do
|
||||||
invalid_params = valid_params.merge(password_confirmation: "wrong")
|
invalid_params = valid_params.merge(password_confirmation: "wrong")
|
||||||
|
|
||||||
response = AppClient.exec(Api::SignUps::Create, user: invalid_params)
|
response = AppClient.exec(Api::SignUp::Create, user: invalid_params)
|
||||||
|
|
||||||
UserQuery.new.select_count.should eq(0)
|
UserQuery.new.select_count.should eq(0)
|
||||||
response.should send_json(
|
response.should send_json(
|
||||||
|
@ -27,6 +28,7 @@ end
|
||||||
|
|
||||||
private def valid_params
|
private def valid_params
|
||||||
{
|
{
|
||||||
|
name: "test",
|
||||||
email: "test@email.com",
|
email: "test@email.com",
|
||||||
password: "password",
|
password: "password",
|
||||||
password_confirmation: "password",
|
password_confirmation: "password",
|
|
@ -1,3 +1,7 @@
|
||||||
|
require "../../tasks/create_required_seeds"
|
||||||
|
|
||||||
Spec.before_each do
|
Spec.before_each do
|
||||||
AppDatabase.truncate
|
AppDatabase.truncate
|
||||||
|
|
||||||
|
Db::CreateRequiredSeeds.new(quiet: true).call
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
class UserBox < Avram::Box
|
class UserBox < Avram::Box
|
||||||
def initialize
|
def initialize
|
||||||
|
name "#{sequence("test")}"
|
||||||
email "#{sequence("test-email")}@example.com"
|
email "#{sequence("test-email")}@example.com"
|
||||||
encrypted_password Authentic.generate_encrypted_password("password")
|
encrypted_password Authentic.generate_encrypted_password("password")
|
||||||
|
primary_role_id RoleQuery.new.name("user").first.id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
class AuthenticationFlow < BaseFlow
|
|
||||||
private getter email
|
|
||||||
|
|
||||||
def initialize(@email : String)
|
|
||||||
end
|
|
||||||
|
|
||||||
def sign_up(password)
|
|
||||||
visit SignUps::New
|
|
||||||
fill_form SignUpUser,
|
|
||||||
email: email,
|
|
||||||
password: password,
|
|
||||||
password_confirmation: password
|
|
||||||
click "@sign-up-button"
|
|
||||||
end
|
|
||||||
|
|
||||||
def sign_out
|
|
||||||
visit Me::Show
|
|
||||||
sign_out_button.click
|
|
||||||
end
|
|
||||||
|
|
||||||
def sign_in(password)
|
|
||||||
visit SignIns::New
|
|
||||||
fill_form SignInUser,
|
|
||||||
email: email,
|
|
||||||
password: password
|
|
||||||
click "@sign-in-button"
|
|
||||||
end
|
|
||||||
|
|
||||||
def should_be_signed_in
|
|
||||||
sign_out_button.should be_on_page
|
|
||||||
end
|
|
||||||
|
|
||||||
def should_have_password_error
|
|
||||||
el("body", text: "Password is wrong").should be_on_page
|
|
||||||
end
|
|
||||||
|
|
||||||
private def sign_out_button
|
|
||||||
el("@sign-out-button")
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,42 +0,0 @@
|
||||||
class ResetPasswordFlow < BaseFlow
|
|
||||||
private getter user, authentication_flow
|
|
||||||
delegate sign_in, sign_out, should_have_password_error, should_be_signed_in,
|
|
||||||
to: authentication_flow
|
|
||||||
delegate email, to: user
|
|
||||||
|
|
||||||
def initialize(@user : User)
|
|
||||||
@authentication_flow = AuthenticationFlow.new(user.email)
|
|
||||||
end
|
|
||||||
|
|
||||||
def request_password_reset
|
|
||||||
with_fake_token do
|
|
||||||
visit PasswordResetRequests::New
|
|
||||||
fill_form RequestPasswordReset,
|
|
||||||
email: email
|
|
||||||
click "@request-password-reset-button"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def should_have_sent_reset_email
|
|
||||||
with_fake_token do
|
|
||||||
user = UserQuery.new.email(email).first
|
|
||||||
PasswordResetRequestEmail.new(user).should be_delivered
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def reset_password(password)
|
|
||||||
user = UserQuery.new.email(email).first
|
|
||||||
token = Authentic.generate_password_reset_token(user)
|
|
||||||
visit PasswordResets::New.with(user.id, token)
|
|
||||||
fill_form ResetPassword,
|
|
||||||
password: password,
|
|
||||||
password_confirmation: password
|
|
||||||
click "@update-password-button"
|
|
||||||
end
|
|
||||||
|
|
||||||
private def with_fake_token
|
|
||||||
PasswordResetRequestEmail.temp_config(stubbed_token: "fake") do
|
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,4 +1,4 @@
|
||||||
class Api::SignIns::Create < ApiAction
|
class Api::SignIn::Create < ApiAction
|
||||||
include Api::Auth::SkipRequireAuthToken
|
include Api::Auth::SkipRequireAuthToken
|
||||||
|
|
||||||
route do
|
route do
|
|
@ -1,4 +1,4 @@
|
||||||
class Api::SignUps::Create < ApiAction
|
class Api::SignUp::Create < ApiAction
|
||||||
include Api::Auth::SkipRequireAuthToken
|
include Api::Auth::SkipRequireAuthToken
|
||||||
|
|
||||||
route do
|
route do
|
|
@ -7,12 +7,12 @@ class Home::Index < BrowserAction
|
||||||
else
|
else
|
||||||
# When you're ready change this line to:
|
# When you're ready change this line to:
|
||||||
#
|
#
|
||||||
# redirect SignIns::New
|
# redirect SignIn::New
|
||||||
#
|
#
|
||||||
# Or maybe show signed out users a marketing page:
|
# Or maybe show signed out users a marketing page:
|
||||||
#
|
#
|
||||||
# html Marketing::IndexPage
|
# html Marketing::IndexPage
|
||||||
redirect SignIns::New
|
redirect SignIn::New
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ module Auth::RequireSignIn
|
||||||
else
|
else
|
||||||
Authentic.remember_requested_path(self)
|
Authentic.remember_requested_path(self)
|
||||||
flash.info = "Please sign in first"
|
flash.info = "Please sign in first"
|
||||||
redirect to: SignIns::New
|
redirect to: SignIn::New
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ class PasswordResetRequests::Create < BrowserAction
|
||||||
if user
|
if user
|
||||||
PasswordResetRequestEmail.new(user).deliver
|
PasswordResetRequestEmail.new(user).deliver
|
||||||
flash.success = "You should receive an email on how to reset your password shortly"
|
flash.success = "You should receive an email on how to reset your password shortly"
|
||||||
redirect SignIns::New
|
redirect SignIn::New
|
||||||
else
|
else
|
||||||
html NewPage, operation: operation
|
html NewPage, operation: operation
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
class SignIns::Create < BrowserAction
|
class SignIn::Create < BrowserAction
|
||||||
include Auth::RedirectSignedInUsers
|
include Auth::RedirectSignedInUsers
|
||||||
|
|
||||||
route do
|
route do
|
|
@ -1,7 +1,7 @@
|
||||||
class SignIns::Delete < BrowserAction
|
class SignIn::Delete < BrowserAction
|
||||||
delete "/sign_out" do
|
delete "/sign_out" do
|
||||||
sign_out
|
sign_out
|
||||||
flash.info = "You have been signed out"
|
flash.info = "You have been signed out"
|
||||||
redirect to: SignIns::New
|
redirect to: SignIn::New
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
class SignIns::New < BrowserAction
|
class SignIn::New < BrowserAction
|
||||||
include Auth::RedirectSignedInUsers
|
include Auth::RedirectSignedInUsers
|
||||||
|
|
||||||
get "/sign_in" do
|
get "/sign_in" do
|
|
@ -1,4 +1,4 @@
|
||||||
class SignUps::Create < BrowserAction
|
class SignUp::Create < BrowserAction
|
||||||
include Auth::RedirectSignedInUsers
|
include Auth::RedirectSignedInUsers
|
||||||
|
|
||||||
route do
|
route do
|
|
@ -1,4 +1,4 @@
|
||||||
class SignUps::New < BrowserAction
|
class SignUp::New < BrowserAction
|
||||||
include Auth::RedirectSignedInUsers
|
include Auth::RedirectSignedInUsers
|
||||||
|
|
||||||
get "/sign_up" do
|
get "/sign_up" do
|
|
@ -3,6 +3,6 @@ class Role < BaseModel
|
||||||
column name : String
|
column name : String
|
||||||
column description : String?
|
column description : String?
|
||||||
|
|
||||||
has_many users : User, foreign_key: :primary_role_id #####
|
has_many users : User, foreign_key: :primary_role_id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,8 @@ class User < BaseModel
|
||||||
table do
|
table do
|
||||||
column name : String
|
column name : String
|
||||||
column encrypted_password : String
|
column encrypted_password : String
|
||||||
column email : String?
|
column email : String
|
||||||
column created_at : Time
|
column created_at : Time, autogenerated: true
|
||||||
|
|
||||||
belongs_to primary_role : Role
|
belongs_to primary_role : Role
|
||||||
has_many posts : Post, foreign_key: :creator_id
|
has_many posts : Post, foreign_key: :creator_id
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
module UserFromName
|
||||||
|
private def user_from_name : User?
|
||||||
|
name.value.try do |value|
|
||||||
|
UserQuery.new.name(value).first?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,14 +1,14 @@
|
||||||
class SignInUser < Avram::Operation
|
class SignInUser < Avram::Operation
|
||||||
param_key :user
|
param_key :user
|
||||||
# You can modify this in src/operations/mixins/user_from_email.cr
|
|
||||||
include UserFromEmail
|
|
||||||
|
|
||||||
attribute email : String
|
include UserFromName
|
||||||
|
|
||||||
|
attribute name : String
|
||||||
attribute password : String
|
attribute password : String
|
||||||
|
|
||||||
# Run validations and yields the operation and the user if valid
|
# Run validations and yields the operation and the user if valid
|
||||||
def submit
|
def submit
|
||||||
user = user_from_email
|
user = user_from_name
|
||||||
validate_credentials(user)
|
validate_credentials(user)
|
||||||
|
|
||||||
if valid?
|
if valid?
|
||||||
|
@ -18,23 +18,15 @@ class SignInUser < Avram::Operation
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# `validate_credentials` determines if a user can sign in.
|
|
||||||
#
|
|
||||||
# If desired, you can add additional checks in this method, e.g.
|
|
||||||
#
|
|
||||||
# if user.locked?
|
|
||||||
# email.add_error "is locked out"
|
|
||||||
# end
|
|
||||||
private def validate_credentials(user)
|
private def validate_credentials(user)
|
||||||
|
# TODO: If banned, disallow login
|
||||||
|
|
||||||
if user
|
if user
|
||||||
unless Authentic.correct_password?(user, password.value.to_s)
|
unless Authentic.correct_password?(user, password.value.to_s)
|
||||||
password.add_error "is wrong"
|
password.add_error "is wrong"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
# Usually ok to say that an email is not in the system:
|
name.add_error "is not in our system"
|
||||||
# https://kev.inburke.com/kevin/invalid-username-or-password-useless/
|
|
||||||
# https://github.com/luckyframework/lucky_cli/issues/192
|
|
||||||
email.add_error "is not in our system"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
class SignUpUser < User::SaveOperation
|
class SignUpUser < User::SaveOperation
|
||||||
param_key :user
|
param_key :user
|
||||||
# Change password validations in src/operations/mixins/password_validations.cr
|
|
||||||
include PasswordValidations
|
include PasswordValidations
|
||||||
|
|
||||||
permit_columns email
|
permit_columns name, email
|
||||||
attribute password : String
|
attribute password : String
|
||||||
attribute password_confirmation : String
|
attribute password_confirmation : String
|
||||||
|
|
||||||
before_save do
|
before_save do
|
||||||
|
primary_role_id.value = RoleQuery.new.name("user").first.id
|
||||||
|
|
||||||
|
validate_uniqueness_of name
|
||||||
validate_uniqueness_of email
|
validate_uniqueness_of email
|
||||||
|
|
||||||
Authentic.copy_and_encrypt password, to: encrypted_password
|
Authentic.copy_and_encrypt password, to: encrypted_password
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,8 +31,8 @@ abstract class MainLayout
|
||||||
end
|
end
|
||||||
|
|
||||||
private def render_signed_in_user
|
private def render_signed_in_user
|
||||||
text @current_user.email
|
text @current_user.name
|
||||||
text " - "
|
text " - "
|
||||||
link "Sign out", to: SignIns::Delete, flow_id: "sign-out-button"
|
link "Sign out", to: SignIn::Delete, flow_id: "sign-out-button"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
class SignIns::NewPage < AuthLayout
|
class SignIn::NewPage < AuthLayout
|
||||||
needs operation : SignInUser
|
needs operation : SignInUser
|
||||||
|
|
||||||
def content
|
def content
|
||||||
|
@ -7,17 +7,17 @@ class SignIns::NewPage < AuthLayout
|
||||||
end
|
end
|
||||||
|
|
||||||
private def render_sign_in_form(op)
|
private def render_sign_in_form(op)
|
||||||
form_for SignIns::Create do
|
form_for SignIn::Create do
|
||||||
sign_in_fields(op)
|
sign_in_fields(op)
|
||||||
submit "Sign In", flow_id: "sign-in-button"
|
submit "Sign In", flow_id: "sign-in-button"
|
||||||
end
|
end
|
||||||
link "Reset password", to: PasswordResetRequests::New
|
link "Reset password", to: PasswordResetRequests::New
|
||||||
text " | "
|
text " | "
|
||||||
link "Sign up", to: SignUps::New
|
link "Sign up", to: SignUp::New
|
||||||
end
|
end
|
||||||
|
|
||||||
private def sign_in_fields(op)
|
private def sign_in_fields(op)
|
||||||
mount Shared::Field.new(op.email), &.email_input(autofocus: "true")
|
mount Shared::Field.new(op.name), &.text_input(autofocus: "true")
|
||||||
mount Shared::Field.new(op.password), &.password_input
|
mount Shared::Field.new(op.password), &.password_input
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
class SignUps::NewPage < AuthLayout
|
class SignUp::NewPage < AuthLayout
|
||||||
needs operation : SignUpUser
|
needs operation : SignUpUser
|
||||||
|
|
||||||
def content
|
def content
|
||||||
|
@ -7,15 +7,16 @@ class SignUps::NewPage < AuthLayout
|
||||||
end
|
end
|
||||||
|
|
||||||
private def render_sign_up_form(op)
|
private def render_sign_up_form(op)
|
||||||
form_for SignUps::Create do
|
form_for SignUp::Create do
|
||||||
sign_up_fields(op)
|
sign_up_fields(op)
|
||||||
submit "Sign Up", flow_id: "sign-up-button"
|
submit "Sign Up", flow_id: "sign-up-button"
|
||||||
end
|
end
|
||||||
link "Sign in instead", to: SignIns::New
|
link "Sign in instead", to: SignIn::New
|
||||||
end
|
end
|
||||||
|
|
||||||
private def sign_up_fields(op)
|
private def sign_up_fields(op)
|
||||||
mount Shared::Field.new(op.email), &.email_input(autofocus: "true")
|
mount Shared::Field.new(op.name), &.text_input(autofocus: "true")
|
||||||
|
mount Shared::Field.new(op.email), &.email_input
|
||||||
mount Shared::Field.new(op.password), &.password_input
|
mount Shared::Field.new(op.password), &.password_input
|
||||||
mount Shared::Field.new(op.password_confirmation), &.password_input
|
mount Shared::Field.new(op.password_confirmation), &.password_input
|
||||||
end
|
end
|
|
@ -3,6 +3,6 @@ class UserSerializer < Lucky::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def render
|
def render
|
||||||
{email: @user.email}
|
{name: @user.name, email: @user.email}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,9 @@ require "../spec/support/boxes/**"
|
||||||
# Use `Db::CreateSampleSeeds` if your only want to add sample data helpful for
|
# Use `Db::CreateSampleSeeds` if your only want to add sample data helpful for
|
||||||
# development.
|
# development.
|
||||||
class Db::CreateRequiredSeeds < LuckyCli::Task
|
class Db::CreateRequiredSeeds < LuckyCli::Task
|
||||||
|
def initialize(@quiet : Bool = false)
|
||||||
|
end
|
||||||
|
|
||||||
summary "Add database records required for the app to work"
|
summary "Add database records required for the app to work"
|
||||||
|
|
||||||
def call
|
def call
|
||||||
|
@ -20,6 +23,8 @@ class Db::CreateRequiredSeeds < LuckyCli::Task
|
||||||
Role::SaveOperation.create!(id: 1000, name: "user", description: "Regular user")
|
Role::SaveOperation.create!(id: 1000, name: "user", description: "Regular user")
|
||||||
end
|
end
|
||||||
|
|
||||||
puts "Done adding required data"
|
unless @quiet
|
||||||
|
puts "Done adding required data"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue