132 lines
2.8 KiB
Ruby
132 lines
2.8 KiB
Ruby
require 'sinatra'
|
|
require 'sinatra/activerecord'
|
|
require 'securerandom'
|
|
require_relative 'models'
|
|
|
|
set :database, {adapter: "sqlite3", database: "db/todoizer.sqlite3"}
|
|
set :sessions, true
|
|
set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
|
|
set :server, 'puma'
|
|
set :port, 4567
|
|
set :bind, '0.0.0.0'
|
|
|
|
# Auto-migrate on startup for simplicity
|
|
ActiveRecord::Schema.define do
|
|
unless ActiveRecord::Base.connection.table_exists?(:users)
|
|
create_table :users do |t|
|
|
t.boolean :is_temporary, default: false
|
|
t.string :username
|
|
t.string :password_digest
|
|
t.timestamps
|
|
end
|
|
end
|
|
|
|
unless ActiveRecord::Base.connection.table_exists?(:todos)
|
|
create_table :todos do |t|
|
|
t.references :user, foreign_key: true
|
|
t.string :content
|
|
t.boolean :is_completed, default: false
|
|
t.timestamps
|
|
end
|
|
end
|
|
end
|
|
|
|
helpers do
|
|
def current_user
|
|
@current_user ||= begin
|
|
if session[:user_id]
|
|
User.find_by(id: session[:user_id])
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
end
|
|
|
|
def ensure_user
|
|
unless current_user
|
|
temp_user = User.create!(is_temporary: true)
|
|
session[:user_id] = temp_user.id
|
|
@current_user = temp_user
|
|
end
|
|
end
|
|
end
|
|
|
|
before do
|
|
ensure_user unless request.path_info == '/login' || request.path_info == '/signup'
|
|
end
|
|
|
|
get '/' do
|
|
@todos = current_user.todos.order(created_at: :desc)
|
|
erb :index
|
|
end
|
|
|
|
post '/todos' do
|
|
if params[:content] && !params[:content].strip.empty?
|
|
current_user.todos.create(content: params[:content].strip)
|
|
end
|
|
redirect '/'
|
|
end
|
|
|
|
post '/todos/:id/toggle' do
|
|
todo = current_user.todos.find_by(id: params[:id])
|
|
todo.update(is_completed: !todo.is_completed) if todo
|
|
redirect '/'
|
|
end
|
|
|
|
post '/todos/:id/delete' do
|
|
todo = current_user.todos.find_by(id: params[:id])
|
|
todo.destroy if todo
|
|
redirect '/'
|
|
end
|
|
|
|
get '/signup' do
|
|
redirect '/' unless current_user&.is_temporary
|
|
erb :signup
|
|
end
|
|
|
|
post '/signup' do
|
|
redirect '/' unless current_user&.is_temporary
|
|
|
|
username = params[:username].to_s.strip
|
|
password = params[:password].to_s.strip
|
|
|
|
if username.empty? || password.empty?
|
|
@error = "Username and password are required."
|
|
return erb :signup
|
|
end
|
|
|
|
if User.exists?(username: username)
|
|
@error = "Username is already taken."
|
|
return erb :signup
|
|
end
|
|
|
|
current_user.update!(
|
|
is_temporary: false,
|
|
username: username,
|
|
password: password
|
|
)
|
|
|
|
redirect '/'
|
|
end
|
|
|
|
get '/login' do
|
|
redirect '/' if current_user && !current_user.is_temporary
|
|
erb :login
|
|
end
|
|
|
|
post '/login' do
|
|
user = User.find_by(username: params[:username], is_temporary: false)
|
|
if user && user.authenticate(params[:password])
|
|
session[:user_id] = user.id
|
|
redirect '/'
|
|
else
|
|
@error = "Invalid username or password"
|
|
erb :login
|
|
end
|
|
end
|
|
|
|
post '/logout' do
|
|
session.clear
|
|
redirect '/'
|
|
end
|