invitation system, user settings
This commit is contained in:
parent
22ae6bc1b2
commit
ada1571a53
|
@ -90,7 +90,7 @@ textarea {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
margin-top: 10px;
|
margin-top: 0.5em;
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
|
|
19
app/controllers/invitations_controller.rb
Normal file
19
app/controllers/invitations_controller.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
class InvitationsController < ApplicationController
|
||||||
|
before_filter :require_logged_in_user
|
||||||
|
|
||||||
|
def create
|
||||||
|
i = Invitation.new
|
||||||
|
i.user_id = @user.id
|
||||||
|
i.email = params[:email]
|
||||||
|
i.memo = params[:memo]
|
||||||
|
if i.save
|
||||||
|
flash[:success] = "Successfully e-mailed invitation to " <<
|
||||||
|
params[:email]
|
||||||
|
else
|
||||||
|
flash[:error] = "Could not send invitation, verify the e-mail " <<
|
||||||
|
"address is valid."
|
||||||
|
end
|
||||||
|
|
||||||
|
return redirect_to "/settings"
|
||||||
|
end
|
||||||
|
end
|
|
@ -21,7 +21,7 @@ class LoginController < ApplicationController
|
||||||
return redirect_to "/"
|
return redirect_to "/"
|
||||||
end
|
end
|
||||||
|
|
||||||
flash[:error] = "Invalid e-mail address and/or password."
|
flash.now[:error] = "Invalid e-mail address and/or password."
|
||||||
index
|
index
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -35,13 +35,14 @@ class LoginController < ApplicationController
|
||||||
params[:email]).first
|
params[:email]).first
|
||||||
|
|
||||||
if !@found_user
|
if !@found_user
|
||||||
flash[:error] = "Invalid e-mail address or username."
|
flash.now[:error] = "Invalid e-mail address or username."
|
||||||
return forgot_password
|
return forgot_password
|
||||||
end
|
end
|
||||||
|
|
||||||
@found_user.initiate_password_reset_for_ip(request.remote_ip)
|
@found_user.initiate_password_reset_for_ip(request.remote_ip)
|
||||||
|
|
||||||
flash[:success] = "Password reset instructions have been e-mailed to you."
|
flash.now[:success] = "Password reset instructions have been e-mailed " <<
|
||||||
|
"to you."
|
||||||
return index
|
return index
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -56,9 +57,11 @@ class LoginController < ApplicationController
|
||||||
if !params[:password].blank?
|
if !params[:password].blank?
|
||||||
@reset_user.password = params[:password]
|
@reset_user.password = params[:password]
|
||||||
@reset_user.password_confirmation = params[:password_confirmation]
|
@reset_user.password_confirmation = params[:password_confirmation]
|
||||||
@reset_user.session_token = nil
|
|
||||||
@reset_user.password_reset_token = nil
|
@reset_user.password_reset_token = nil
|
||||||
|
|
||||||
|
# this will get reset upon save
|
||||||
|
@reset_user.session_token = nil
|
||||||
|
|
||||||
if @reset_user.save
|
if @reset_user.save
|
||||||
session[:u] = @reset_user.session_token
|
session[:u] = @reset_user.session_token
|
||||||
return redirect_to "/"
|
return redirect_to "/"
|
||||||
|
|
18
app/controllers/settings_controller.rb
Normal file
18
app/controllers/settings_controller.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
class SettingsController < ApplicationController
|
||||||
|
before_filter :require_logged_in_user
|
||||||
|
|
||||||
|
def index
|
||||||
|
@edit_user = @user.dup
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@edit_user = @user.clone
|
||||||
|
|
||||||
|
if @edit_user.update_attributes(params[:user])
|
||||||
|
flash.now[:success] = "Successfully updated settings"
|
||||||
|
@user = @edit_user
|
||||||
|
end
|
||||||
|
|
||||||
|
render :action => "index"
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,17 +1,48 @@
|
||||||
class SignupController < ApplicationController
|
class SignupController < ApplicationController
|
||||||
def index
|
def index
|
||||||
@page_title = "Signup"
|
if @user
|
||||||
|
flash[:error] = "You are already signed up."
|
||||||
|
return redirect_to "/"
|
||||||
|
end
|
||||||
|
|
||||||
|
@title = "Signup"
|
||||||
|
@page_title = "Create an Account"
|
||||||
|
end
|
||||||
|
|
||||||
|
def invited
|
||||||
|
if @user
|
||||||
|
flash[:error] = "You are already signed up."
|
||||||
|
return redirect_to "/"
|
||||||
|
end
|
||||||
|
|
||||||
|
@title = "Signup"
|
||||||
|
@page_title = "Create an Account"
|
||||||
|
|
||||||
|
if !(@invitation = Invitation.find_by_code(params[:invitation_code]))
|
||||||
|
flash[:error] = "Invalid or expired invitation"
|
||||||
|
return redirect_to "/signup"
|
||||||
|
end
|
||||||
|
|
||||||
@new_user = User.new
|
@new_user = User.new
|
||||||
|
render :action => "invited"
|
||||||
end
|
end
|
||||||
|
|
||||||
def signup
|
def signup
|
||||||
|
if !(@invitation = Invitation.find_by_code(params[:invitation_code]))
|
||||||
|
flash[:error] = "Invalid or expired invitation"
|
||||||
|
return redirect_to "/signup"
|
||||||
|
end
|
||||||
|
|
||||||
@new_user = User.new(params[:user])
|
@new_user = User.new(params[:user])
|
||||||
|
@new_user.invited_by_user_id = @invitation.user_id
|
||||||
|
|
||||||
if @new_user.save
|
if @new_user.save
|
||||||
|
@invitation.destroy
|
||||||
session[:u] = @new_user.session_token
|
session[:u] = @new_user.session_token
|
||||||
|
flash[:success] = "Welcome to Lobsters, #{@new_user.username}"
|
||||||
return redirect_to "/"
|
return redirect_to "/"
|
||||||
else
|
else
|
||||||
render :action => "index"
|
render :action => "invited"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -162,8 +162,8 @@ private
|
||||||
end
|
end
|
||||||
|
|
||||||
if !@story
|
if !@story
|
||||||
flash[:error] = "Could not find story or you are not authorized to " <<
|
flash[:error] = "Could not find story or you are not authorized " <<
|
||||||
"manage it."
|
"to manage it."
|
||||||
redirect_to "/"
|
redirect_to "/"
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
2
app/helpers/invitations_helper.rb
Normal file
2
app/helpers/invitations_helper.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
module InvitationsHelper
|
||||||
|
end
|
2
app/helpers/settings_helper.rb
Normal file
2
app/helpers/settings_helper.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
module SettingsHelper
|
||||||
|
end
|
|
@ -24,7 +24,7 @@ class Comment < ActiveRecord::Base
|
||||||
|
|
||||||
self.story_id.blank? &&
|
self.story_id.blank? &&
|
||||||
errors.add(:story_id, "cannot be blank.")
|
errors.add(:story_id, "cannot be blank.")
|
||||||
|
|
||||||
(m = self.comment.to_s.strip.match(/\A(t)his([\.!])?$\z/i)) &&
|
(m = self.comment.to_s.strip.match(/\A(t)his([\.!])?$\z/i)) &&
|
||||||
errors.add(:base, (m[1] == "T" ? "N" : "n") + "ope" + m[2].to_s)
|
errors.add(:base, (m[1] == "T" ? "N" : "n") + "ope" + m[2].to_s)
|
||||||
end
|
end
|
||||||
|
@ -80,14 +80,14 @@ class Comment < ActiveRecord::Base
|
||||||
Markdowner.markdown(self.comment)
|
Markdowner.markdown(self.comment)
|
||||||
end
|
end
|
||||||
|
|
||||||
def upvote!(amount = 1)
|
|
||||||
Story.update_counters self.id, :upvotes => amount
|
|
||||||
end
|
|
||||||
|
|
||||||
def flag!
|
def flag!
|
||||||
Story.update_counters self.id, :flaggings => 1
|
Story.update_counters self.id, :flaggings => 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_been_edited?
|
||||||
|
self.updated_at && (self.updated_at - self.created_at > 1.minute)
|
||||||
|
end
|
||||||
|
|
||||||
def self.ordered_for_story_or_thread_for_user(story_id, thread_id, user_id)
|
def self.ordered_for_story_or_thread_for_user(story_id, thread_id, user_id)
|
||||||
parents = {}
|
parents = {}
|
||||||
|
|
||||||
|
|
28
app/models/invitation.rb
Normal file
28
app/models/invitation.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
class Invitation < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
validate do
|
||||||
|
if !email.to_s.match(/\A[^@]+@[^@]+\.[^@]+\z/)
|
||||||
|
errors.add(:email, "is not valid")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
before_create :create_code
|
||||||
|
after_create :send_email
|
||||||
|
|
||||||
|
def create_code
|
||||||
|
(1...10).each do |tries|
|
||||||
|
if tries == 10
|
||||||
|
raise "too many hash collisions"
|
||||||
|
end
|
||||||
|
|
||||||
|
if !Invitation.find_by_code(self.code = Utils.random_str(15))
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_email
|
||||||
|
InvitationMailer.invitation(self).deliver
|
||||||
|
end
|
||||||
|
end
|
10
app/models/invitation_mailer.rb
Normal file
10
app/models/invitation_mailer.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
class InvitationMailer < ActionMailer::Base
|
||||||
|
default from: "nobody@lobste.rs"
|
||||||
|
|
||||||
|
def invitation(invitation)
|
||||||
|
@invitation = invitation
|
||||||
|
|
||||||
|
mail(to: invitation.email, from: "Lobsters Invitation <nobody@lobste.rs>",
|
||||||
|
subject: "[Lobsters] Welcome to Lobsters")
|
||||||
|
end
|
||||||
|
end
|
|
@ -80,7 +80,8 @@ class Story < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def comments_url
|
def comments_url
|
||||||
"/s/#{self.short_id}/#{self.title_as_url}"
|
Rails.application.routes.url_helpers.root_url +
|
||||||
|
"s/#{self.short_id}/#{self.title_as_url}"
|
||||||
end
|
end
|
||||||
|
|
||||||
@_comment_count = nil
|
@_comment_count = nil
|
||||||
|
|
|
@ -12,7 +12,8 @@ class User < ActiveRecord::Base
|
||||||
validates_presence_of :password, :on => :create
|
validates_presence_of :password, :on => :create
|
||||||
|
|
||||||
attr_accessible :username, :email, :password, :password_confirmation,
|
attr_accessible :username, :email, :password, :password_confirmation,
|
||||||
:email_notifications
|
:about, :email_replies, :pushover_replies, :pushover_user_key,
|
||||||
|
:pushover_device
|
||||||
|
|
||||||
before_save :check_session_token
|
before_save :check_session_token
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ class User < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def initiate_password_reset_for_ip(ip)
|
def initiate_password_reset_for_ip(ip)
|
||||||
self.password_reset_token = Utils.random_str(60)
|
self.password_reset_token = Utils.random_str(45)
|
||||||
self.save!
|
self.save!
|
||||||
|
|
||||||
PasswordReset.password_reset_link(self, ip).deliver
|
PasswordReset.password_reset_link(self, ip).deliver
|
||||||
|
|
|
@ -22,8 +22,9 @@ class="comment <%= comment.current_vote ? (comment.current_vote[:vote] == 1 ?
|
||||||
<a href="/u/<%= comment.user.username %>"><%= comment.user.username
|
<a href="/u/<%= comment.user.username %>"><%= comment.user.username
|
||||||
%></a>
|
%></a>
|
||||||
|
|
||||||
<%= comment.updated_at ? "edited" : "" %>
|
<%= comment.has_been_edited?? "edited" : "" %>
|
||||||
<%= time_ago_in_words(comment.created_at).gsub(/^about /, "") %> ago
|
<%= time_ago_in_words(comment.has_been_edited?? comment.updated_at :
|
||||||
|
comment.created_at).gsub(/^about /, "") %> ago
|
||||||
|
|
||||||
<span class="reason"><%= comment.current_vote &&
|
<span class="reason"><%= comment.current_vote &&
|
||||||
comment.current_vote[:vote] == -1 ?
|
comment.current_vote[:vote] == -1 ?
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<div id="headerright" class="<%= @user ? "loggedin" : "" %>">
|
<div id="headerright" class="<%= @user ? "loggedin" : "" %>">
|
||||||
<% if @user %>
|
<% if @user %>
|
||||||
<a href="/u/<%= @user.username %>"><%= @user.username
|
<a href="/settings"><%= @user.username %> (<%= @user.karma %>)</a>
|
||||||
%> (<%= @user.karma %>)</a>
|
|
||||||
|
|
||||||
<% if false %>
|
<% if false %>
|
||||||
<% if (count = @user.unread_message_count) > 0 %>
|
<% if (count = @user.unread_message_count) > 0 %>
|
||||||
|
@ -16,8 +15,6 @@
|
||||||
{ :confirm => "Are you sure you want to logout?",
|
{ :confirm => "Are you sure you want to logout?",
|
||||||
"method" => "post" } %>
|
"method" => "post" } %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<a href="/signup">Signup</a>
|
|
||||||
or
|
|
||||||
<a href="/login">Login</a>
|
<a href="/login">Login</a>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<channel>
|
<channel>
|
||||||
<title>lobste.rs<%= @page_title ? ": " + h(@page_title) : "" %></title>
|
<title>lobste.rs<%= @page_title ? ": " + h(@page_title) : "" %></title>
|
||||||
<description><%= @page_title %></description>
|
<description><%= @page_title %></description>
|
||||||
<link>http://lobste.rs/<%= @newest ? "newest" : "" %></link>
|
<link><%= root_url + (@newest ? "newest" : "") %></link>
|
||||||
|
|
||||||
<% @stories.each do |story| %>
|
<% @stories.each do |story| %>
|
||||||
<item>
|
<item>
|
||||||
|
|
9
app/views/invitation_mailer/invitation.text.erb
Normal file
9
app/views/invitation_mailer/invitation.text.erb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Hello <%= @invitation.email %>,
|
||||||
|
|
||||||
|
The user <%= @invitation.user.username %> has invited you to the website Lobsters:
|
||||||
|
|
||||||
|
<%= @invitation.memo %>
|
||||||
|
|
||||||
|
To create an account, visit the URL below:
|
||||||
|
|
||||||
|
<%= root_url %>invitations/<%= @invitation.code %>
|
|
@ -24,7 +24,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Not signed up yet? <%= link_to "Signup", signup_url %>.
|
Not a user yet? Lobsters is currently invitation-only.
|
||||||
</p>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Hello <%= @user.email %>,
|
Hello <%= @user.email %>,
|
||||||
|
|
||||||
Someone at <%= @ip %> requested to reset your account password.
|
Someone at <%= @ip %> requested to reset your account password
|
||||||
If you submitted this request, visit the link below to set a new password.
|
on lobste.rs. If you submitted this request, visit the link below to
|
||||||
If not, you can disregard this e-mail.
|
set a new password. If not, you can disregard this e-mail.
|
||||||
|
|
||||||
http://lobste.rs/login/set_new_password?token=<%= @user.password_reset_token %>
|
<%= root_url %>login/set_new_password?token=<%= @user.password_reset_token %>
|
||||||
|
|
108
app/views/settings/index.html.erb
Normal file
108
app/views/settings/index.html.erb
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
<div class="box wide">
|
||||||
|
<div style="float: right;">
|
||||||
|
<a href="/u/<%= @user.username %>">View Profile</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legend">
|
||||||
|
Invite a New User
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= form_tag "/invitations", :method => :post do |f| %>
|
||||||
|
<div class="boxline">
|
||||||
|
<%= label_tag :email, "E-mail Address:", :class => "required" %>
|
||||||
|
<%= text_field_tag :email, "", :size => 30 %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= label_tag :memo, "Memo to User:", :class => "required" %>
|
||||||
|
<%= text_field_tag :memo, "", :size => 60 %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<p></p>
|
||||||
|
<%= submit_tag "Send Invitation" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="legend">
|
||||||
|
Account Settings
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= form_for @edit_user, :url => settings_url, :method => :post do |f| %>
|
||||||
|
<%= error_messages_for f.object %>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= f.label :username, "Username:", :class => "required" %>
|
||||||
|
<%= f.text_field :username %>
|
||||||
|
<span class="hint">
|
||||||
|
<tt>[A-Za-z0-9][A-Za-z0-9_-]*</tt>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= f.label :email, "E-mail Address:", :class => "required" %>
|
||||||
|
<%= f.text_field :email %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= f.label :password, "New Password:", :class => "required" %>
|
||||||
|
<%= f.password_field :password %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= f.label :password_confirmation, "Confirm Password:",
|
||||||
|
:class => "required" %>
|
||||||
|
<%= f.password_field :password_confirmation %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= f.label :about, "About:", :class => "required" %>
|
||||||
|
<%= f.text_area :about, :size => "100x5" %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<div class="boxline markdown_help_toggler" style="margin-left: 9em;">
|
||||||
|
<div class="markdown_help_label">
|
||||||
|
<span class="fakea">Limited Markdown formatting available</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="clear: both;"></div>
|
||||||
|
|
||||||
|
<%= render :partial => "global/markdownhelp" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legend">
|
||||||
|
Reply Notification Settings
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= f.label :email_replies, "E-mail:", :class => "required" %>
|
||||||
|
<%= f.check_box :email_replies %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= f.label :pushover_replies, raw("<a href=\"https://pushover.net/\">" +
|
||||||
|
"Pushover</a>:"), :class => "required" %>
|
||||||
|
<%= f.check_box :pushover_replies %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= f.label :pushover_user_key, "Pushover User Key:",
|
||||||
|
:class => "required" %>
|
||||||
|
<%= f.text_field :pushover_user_key, :size => 40 %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="boxline">
|
||||||
|
<%= f.label :pushover_device, "Pushover Device:",
|
||||||
|
:class => "required" %>
|
||||||
|
<%= f.text_field :pushover_device, :placeholder => "optional",
|
||||||
|
:size => 15 %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<%= f.submit "Save All Settings" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
|
@ -3,40 +3,5 @@
|
||||||
Create an Account
|
Create an Account
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= form_for @new_user, { :url => signup_url,
|
Signup is currently by invitation only.
|
||||||
:autocomplete => "off" } do |f| %>
|
</div>
|
||||||
<p>
|
|
||||||
To create a new account, enter your e-mail address and a password.
|
|
||||||
Your e-mail address will never be shown to users and will only be used
|
|
||||||
if you need to reset your password, or to receive optional new-message
|
|
||||||
alerts.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<%= error_messages_for(@new_user) %>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<%= f.label :username, "Username:" %>
|
|
||||||
<%= f.text_field :username, :size => 30 %>
|
|
||||||
<span class="hint">
|
|
||||||
<tt>[A-Za-z0-9][A-Za-z0-9_-]*</tt>
|
|
||||||
</span>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<%= f.label :email, "E-mail Address:" %>
|
|
||||||
<%= f.email_field :email, :size => 30 %>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<%= f.label :password, "Password:" %>
|
|
||||||
<%= f.password_field :password, :size => 30 %>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<%= f.label :password_confirmation, "Password (again):" %>
|
|
||||||
<%= f.password_field :password_confirmation, :size => 30 %>
|
|
||||||
<br />
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<%= submit_tag "Signup" %>
|
|
||||||
</p>
|
|
||||||
<% end %>
|
|
||||||
</fieldset>
|
|
||||||
|
|
51
app/views/signup/invited.html.erb
Normal file
51
app/views/signup/invited.html.erb
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<div class="box wide">
|
||||||
|
<div class="legend">
|
||||||
|
Create an Account
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= form_for @new_user, { :url => signup_url,
|
||||||
|
:autocomplete => "off" } do |f| %>
|
||||||
|
<%= hidden_field_tag "invitation_code", @invitation.code %>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To create a new account, enter your e-mail address and a password.
|
||||||
|
Your e-mail address will never be shown to users and will only be used
|
||||||
|
if you need to reset your password, or to receive optional new-message
|
||||||
|
alerts.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<%= error_messages_for(@new_user) %>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= f.label :invitation, "Invited By:" %>
|
||||||
|
<span class="d">
|
||||||
|
<%= @invitation.user.username %>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= f.label :username, "Username:" %>
|
||||||
|
<%= f.text_field :username, :size => 30 %>
|
||||||
|
<span class="hint">
|
||||||
|
<tt>[A-Za-z0-9][A-Za-z0-9_-]*</tt>
|
||||||
|
</span>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<%= f.label :email, "E-mail Address:" %>
|
||||||
|
<%= f.email_field :email, :size => 30 %>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<%= f.label :password, "Password:" %>
|
||||||
|
<%= f.password_field :password, :size => 30 %>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<%= f.label :password_confirmation, "Password (again):" %>
|
||||||
|
<%= f.password_field :password_confirmation, :size => 30 %>
|
||||||
|
<br />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= submit_tag "Signup" %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
|
@ -1,4 +1,10 @@
|
||||||
<div class="box wide">
|
<div class="box wide">
|
||||||
|
<% if @user && @user.id == @showing_user.id %>
|
||||||
|
<div style="float: right;">
|
||||||
|
<a href="/settings">Edit Settings</a>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<div class="legend">
|
<div class="legend">
|
||||||
<%= @showing_user.username %>
|
<%= @showing_user.username %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -57,3 +57,5 @@ module Lobsters
|
||||||
config.assets.version = '1.0'
|
config.assets.version = '1.0'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Rails.application.routes.default_url_options[:host] = "lobste.rs"
|
||||||
|
|
|
@ -35,3 +35,5 @@ Lobsters::Application.configure do
|
||||||
# Expands the lines which load the assets
|
# Expands the lines which load the assets
|
||||||
config.assets.debug = true
|
config.assets.debug = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Rails.application.routes.default_url_options[:host] = "lobsters.localhost:3000"
|
||||||
|
|
|
@ -41,4 +41,10 @@ Lobsters::Application.routes.draw do
|
||||||
get "/u/:id" => "users#show"
|
get "/u/:id" => "users#show"
|
||||||
|
|
||||||
get "/rss" => "home#index", :format => "rss"
|
get "/rss" => "home#index", :format => "rss"
|
||||||
|
|
||||||
|
get "/settings" => "settings#index"
|
||||||
|
post "/settings" => "settings#update"
|
||||||
|
|
||||||
|
post "/invitations" => "invitations#create"
|
||||||
|
get "/invitations/:invitation_code" => "signup#invited"
|
||||||
end
|
end
|
||||||
|
|
12
db/migrate/20120701154453_create_invitations.rb
Normal file
12
db/migrate/20120701154453_create_invitations.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class CreateInvitations < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :invitations do |t|
|
||||||
|
t.integer :user_id
|
||||||
|
t.string :email
|
||||||
|
t.string :code
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
add_column :users, :invited_by_user_id, :integer
|
||||||
|
end
|
||||||
|
end
|
11
db/migrate/20120701160006_reply_notifications.rb
Normal file
11
db/migrate/20120701160006_reply_notifications.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class ReplyNotifications < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :users, :email_replies, :boolean, :default => false
|
||||||
|
add_column :users, :pushover_replies, :boolean, :default => false
|
||||||
|
add_column :users, :pushover_user_key, :string
|
||||||
|
add_column :users, :pushover_device, :string
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
end
|
||||||
|
end
|
8
db/migrate/20120701181319_invitation_memo.rb
Normal file
8
db/migrate/20120701181319_invitation_memo.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
class InvitationMemo < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :invitations, :memo, :text
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
end
|
||||||
|
end
|
28
db/schema.rb
28
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 0) do
|
ActiveRecord::Schema.define(:version => 20120701181319) do
|
||||||
|
|
||||||
create_table "comments", :force => true do |t|
|
create_table "comments", :force => true do |t|
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
|
@ -27,9 +27,18 @@ ActiveRecord::Schema.define(:version => 0) do
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "comments", ["short_id"], :name => "short_id", :unique => true
|
add_index "comments", ["short_id"], :name => "short_id", :unique => true
|
||||||
add_index "comments", ["story_id", "short_id"], :name => "story_id_short_id"
|
add_index "comments", ["story_id", "short_id"], :name => "story_id"
|
||||||
add_index "comments", ["thread_id"], :name => "thread_id"
|
add_index "comments", ["thread_id"], :name => "thread_id"
|
||||||
|
|
||||||
|
create_table "invitations", :force => true do |t|
|
||||||
|
t.integer "user_id"
|
||||||
|
t.string "email"
|
||||||
|
t.string "code"
|
||||||
|
t.datetime "created_at", :null => false
|
||||||
|
t.datetime "updated_at", :null => false
|
||||||
|
t.text "memo"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "keystores", :primary_key => "key", :force => true do |t|
|
create_table "keystores", :primary_key => "key", :force => true do |t|
|
||||||
t.integer "value", :null => false
|
t.integer "value", :null => false
|
||||||
end
|
end
|
||||||
|
@ -66,7 +75,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
||||||
t.integer "tag_id", :null => false
|
t.integer "tag_id", :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "taggings", ["story_id", "tag_id"], :name => "story_id_tag_id", :unique => true
|
add_index "taggings", ["story_id", "tag_id"], :name => "story_id", :unique => true
|
||||||
|
|
||||||
create_table "tags", :force => true do |t|
|
create_table "tags", :force => true do |t|
|
||||||
t.string "tag", :limit => 25, :default => "", :null => false
|
t.string "tag", :limit => 25, :default => "", :null => false
|
||||||
|
@ -81,10 +90,15 @@ ActiveRecord::Schema.define(:version => 0) do
|
||||||
t.string "password_digest", :limit => 75
|
t.string "password_digest", :limit => 75
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.integer "email_notifications", :limit => 1, :default => 0
|
t.integer "email_notifications", :limit => 1, :default => 0
|
||||||
t.integer "is_admin", :limit => 1, :default => 0, :null => false
|
t.integer "is_admin", :limit => 1, :default => 0, :null => false
|
||||||
t.string "password_reset_token", :limit => 75
|
t.string "password_reset_token", :limit => 75
|
||||||
t.string "session_token", :limit => 75, :default => "", :null => false
|
t.string "session_token", :limit => 75, :default => "", :null => false
|
||||||
t.text "about"
|
t.text "about"
|
||||||
|
t.integer "invited_by_user_id"
|
||||||
|
t.boolean "email_replies", :default => false
|
||||||
|
t.boolean "pushover_replies", :default => false
|
||||||
|
t.string "pushover_user_key"
|
||||||
|
t.string "pushover_device"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["session_token"], :name => "session_hash", :unique => true
|
add_index "users", ["session_token"], :name => "session_hash", :unique => true
|
||||||
|
@ -98,7 +112,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
||||||
t.string "reason", :limit => 1
|
t.string "reason", :limit => 1
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "votes", ["user_id", "comment_id"], :name => "user_id_comment_id"
|
add_index "votes", ["user_id", "comment_id"], :name => "user_id_2"
|
||||||
add_index "votes", ["user_id", "story_id"], :name => "user_id_story_id"
|
add_index "votes", ["user_id", "story_id"], :name => "user_id"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue