1
0
مراية لـ https://github.com/postalserver/postal.git تم المزامنة 2025-12-01 05:43:04 +00:00

initial commit from appmail

هذا الالتزام موجود في:
Adam Cooke
2017-04-19 13:07:25 +01:00
الأصل a3eff53792
التزام 2fdba0ceb5
474 ملفات معدلة مع 51228 إضافات و0 حذوفات

عرض الملف

@@ -0,0 +1,45 @@
class AddressEndpointsController < ApplicationController
include WithinOrganization
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
before_action { params[:id] && @address_endpoint = @server.address_endpoints.find_by_uuid!(params[:id]) }
def index
@address_endpoints = @server.address_endpoints.order(:address).to_a
end
def new
@address_endpoint = @server.address_endpoints.build
end
def create
@address_endpoint = @server.address_endpoints.build(safe_params)
if @address_endpoint.save
flash[:notice] = params[:return_notice] if params[:return_notice].present?
redirect_to_with_json [:return_to, [organization, @server, :address_endpoints]]
else
render_form_errors 'new', @address_endpoint
end
end
def update
if @address_endpoint.update(safe_params)
redirect_to_with_json [organization, @server, :address_endpoints]
else
render_form_errors 'edit', @address_endpoint
end
end
def destroy
@address_endpoint.destroy
redirect_to_with_json [organization, @server, :address_endpoints]
end
private
def safe_params
params.require(:address_endpoint).permit(:address)
end
end

عرض الملف

@@ -0,0 +1,10 @@
class Admin::OrganizationsController < ApplicationController
before_action :admin_required
before_action { params[:id] && @organization = Organization.find_by_permalink!(params[:id]) }
def index
@organizations = Organization.order(:created_at => :desc).includes(:owner).page(params[:page])
end
end

عرض الملف

@@ -0,0 +1,10 @@
class Admin::StatsController < ApplicationController
before_action :admin_required
def stats
@stats = Statistic.global
@queue_size = QueuedMessage.unlocked.retriable.count
end
end

عرض الملف

@@ -0,0 +1,131 @@
require 'authie/session'
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :login_required
before_action :verified_email_required
before_action :set_timezone
rescue_from Authie::Session::InactiveSession, :with => :auth_session_error
rescue_from Authie::Session::ExpiredSession, :with => :auth_session_error
rescue_from Authie::Session::BrowserMismatch, :with => :auth_session_error
private
def login_required
unless logged_in?
redirect_to login_path(:return_to => request.fullpath)
end
end
def admin_required
if logged_in?
unless current_user.admin?
render :text => "Not permitted"
end
else
redirect_to login_path(:return_to => request.fullpath)
end
end
def verified_email_required
if logged_in? && !current_user.verified?
redirect_to verify_path(:return_to => request.fullpath)
end
end
def require_organization_admin
unless organization.admin?(current_user)
redirect_to organization_root_path(organization), :alert => "This page can only be accessed by the organization admins"
end
end
def require_organization_owner
unless organization.owner == current_user
redirect_to organization_root_path(organization), :alert => "This page can only be accessed by the organization's owner (#{organization.owner.name})"
end
end
def auth_session_error(exception)
Rails.logger.info "AuthSessionError: #{exception.class}: #{exception.message}"
redirect_to login_path(:return_to => request.fullpath)
end
def page_title
@page_title ||= ["Postal"]
end
helper_method :page_title
def redirect_to_with_return_to(url, *args)
if params[:return_to].blank? || !params[:return_to].starts_with?('/')
redirect_to url_with_return_to(url), *args
else
redirect_to url_with_return_to(url), *args
end
end
def set_timezone
Time.zone = logged_in? ? current_user.time_zone : 'UTC'
end
def append_info_to_payload(payload)
super
payload[:ip] = request.ip
payload[:user] = logged_in? ? current_user.id : nil
end
def url_with_return_to(url)
if params[:return_to].blank? || !params[:return_to].starts_with?('/')
url_for(url)
else
params[:return_to]
end
end
def redirect_to_with_json(url, flash_messages = {})
if url.is_a?(Array) && url[0] == :return_to
url = url_with_return_to(url[1])
else
url = url_for(url)
end
flash_messages.each do |key, value|
flash[key] = value
end
respond_to do |wants|
wants.html { redirect_to url }
wants.json { render :json => {:redirect_to => url} }
end
end
def render_form_errors(action_name, object)
respond_to do |wants|
wants.html { render action_name }
wants.json { render :json => {:form_errors => object.errors.full_messages}, :status => 422 }
end
end
def flash_now(type, message, options = {})
respond_to do |wants|
wants.html do
flash.now[type] = message
if options[:render_action]
render options[:render_action]
end
end
wants.json { render :json => {:flash => {type => message}} }
end
end
def login(user)
if logged_in?
auth_session.invalidate!
reset_session
end
Authie::Session.start(self, :user => user)
@current_user = user
end
end

عرض الملف

عرض الملف

@@ -0,0 +1,20 @@
module WithinOrganization
extend ActiveSupport::Concern
included do
helper_method :organization
before_action :add_organization_to_page_title
end
private
def organization
@organization ||= current_user.organizations_scope.find_by_permalink!(params[:org_permalink])
end
def add_organization_to_page_title
page_title << organization.name
end
end

عرض الملف

@@ -0,0 +1,38 @@
class CredentialsController < ApplicationController
include WithinOrganization
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
before_action { params[:id] && @credential = @server.credentials.find_by_key!(params[:id]) }
def index
@credentials = @server.credentials.order(:name).to_a
end
def new
@credential = @server.credentials.build
end
def create
@credential = @server.credentials.build(params.require(:credential).permit(:type, :name, :hold))
if @credential.save
redirect_to_with_json [organization, @server, :credentials]
else
render_form_errors 'new', @credential
end
end
def update
if @credential.update(params.require(:credential).permit(:name, :hold))
redirect_to_with_json [organization, @server, :credentials]
else
render_form_errors 'edit', @credential
end
end
def destroy
@credential.destroy
redirect_to_with_json [organization, @server, :credentials]
end
end

عرض الملف

@@ -0,0 +1,102 @@
class DomainsController < ApplicationController
include WithinOrganization
before_action do
if params[:server_id]
@server = organization.servers.present.find_by_permalink!(params[:server_id])
params[:id] && @domain = @server.domains.find_by_uuid!(params[:id])
else
params[:id] && @domain = organization.domains.find_by_uuid!(params[:id])
end
end
def index
if @server
@domains = @server.domains.order(:name).to_a
else
@domains = organization.domains.order(:name).to_a
end
end
def new
@domain = @server ? @server.domains.build : organization.domains.build
end
def create
scope = @server ? @server.domains : organization.domains
@domain = scope.build(params.require(:domain).permit(:name, :verification_method))
if @domain.save
if @auto_verified
flash[:notice] = "Ownership of this domain does not need to be verified because it already has been verified in this organization."
redirect_to_with_json [:setup, organization, @server, @domain]
else
redirect_to_with_json [:verify, organization, @server, @domain]
end
else
render_form_errors 'new', @domain
end
end
def destroy
@domain.destroy
redirect_to_with_json [organization, @server, :domains]
end
def verify
if @domain.verified?
redirect_to [organization, @server, :domains], :alert => "#{@domain.name} has already been verified."
return
end
if request.post?
case @domain.verification_method
when 'DNS'
if @domain.verify_with_dns
redirect_to_with_json [:setup, organization, @server, @domain], :notice => "#{@domain.name} has been verified successfully. You now need to configure your DNS records."
else
respond_to do |wants|
wants.html { flash.now[:alert] = "We couldn't verify your domain. Please double check you've added the TXT record correctly." }
wants.json { render :json => {:flash => {:alert => "We couldn't verify your domain. Please double check you've added the TXT record correctly."}}}
end
end
when 'Email'
if params[:code]
if @domain.verification_token == params[:code].to_s.strip
@domain.verify
redirect_to_with_json [:setup, organization, @server, @domain], :notice => "#{@domain.name} has been verified successfully. You now need to configure your DNS records."
else
respond_to do |wants|
wants.html { flash.now[:alert] = "Invalid verification code. Please check and try again." }
wants.json { render :json => {:flash => {:alert => "Invalid verification code. Please check and try again."}}}
end
end
elsif params[:email_address].present?
raise Postal::Error, "Invalid email address" unless @domain.verification_email_addresses.include?(params[:email_address])
AppMailer.verify_domain(@domain, params[:email_address], current_user).deliver
if @domain.owner.is_a?(Server)
redirect_to_with_json verify_organization_server_domain_path(organization, @server, @domain, :email_address => params[:email_address])
else
redirect_to_with_json verify_organization_domain_path(organization, @domain, :email_address => params[:email_address])
end
end
end
end
end
def setup
unless @domain.verified?
redirect_to [:verify, organization, @server, @domain], :alert => "You can't set up DNS for this domain until it has been verified."
end
end
def check
if @domain.check_dns(:manual)
redirect_to_with_json [organization, @server, :domains], :notice => "Your DNS records for #{@domain.name} look good!"
else
redirect_to_with_json [:setup, organization, @server, @domain], :alert => "There seems to be something wrong with your DNS records. Check below for information."
end
end
end

عرض الملف

@@ -0,0 +1,11 @@
class HelpController < ApplicationController
include WithinOrganization
before_action { @server = organization.servers.find_by_permalink!(params[:server_id]) }
def outgoing
@credentials = @server.credentials.group_by(&:type)
end
end

عرض الملف

@@ -0,0 +1,45 @@
class HTTPEndpointsController < ApplicationController
include WithinOrganization
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
before_action { params[:id] && @http_endpoint = @server.http_endpoints.find_by_uuid!(params[:id]) }
def index
@http_endpoints = @server.http_endpoints.order(:name).to_a
end
def new
@http_endpoint = @server.http_endpoints.build
end
def create
@http_endpoint = @server.http_endpoints.build(safe_params)
if @http_endpoint.save
flash[:notice] = params[:return_notice] if params[:return_notice].present?
redirect_to_with_json [:return_to, [organization, @server, :http_endpoints]]
else
render_form_errors 'new', @http_endpoint
end
end
def update
if @http_endpoint.update(safe_params)
redirect_to_with_json [organization, @server, :http_endpoints]
else
render_form_errors 'edit', @http_endpoint
end
end
def destroy
@http_endpoint.destroy
redirect_to_with_json [organization, @server, :http_endpoints]
end
private
def safe_params
params.require(:http_endpoint).permit(:name, :url, :encoding, :format, :strip_replies, :include_attachments, :timeout)
end
end

عرض الملف

@@ -0,0 +1,55 @@
class IPPoolRulesController < ApplicationController
include WithinOrganization
before_action do
if params[:server_id]
@server = organization.servers.present.find_by_permalink!(params[:server_id])
params[:id] && @ip_pool_rule = @server.ip_pool_rules.find_by_uuid!(params[:id])
else
params[:id] && @ip_pool_rule = organization.ip_pool_rules.find_by_uuid!(params[:id])
end
end
def index
if @server
@ip_pool_rules = @server.ip_pool_rules
else
@ip_pool_rules = organization.ip_pool_rules
end
end
def new
@ip_pool_rule = @server ? @server.ip_pool_rules.build : organization.ip_pool_rules.build
end
def create
scope = @server ? @server.ip_pool_rules : organization.ip_pool_rules
@ip_pool_rule = scope.build(safe_params)
if @ip_pool_rule.save
redirect_to_with_json [organization, @server, :ip_pool_rules]
else
render_form_errors 'new', @ip_pool_rule
end
end
def update
if @ip_pool_rule.update(safe_params)
redirect_to_with_json [organization, @server, :ip_pool_rules]
else
render_form_errors 'edit', @ip_pool_rule
end
end
def destroy
@ip_pool_rule.destroy
redirect_to_with_json [organization, @server, :ip_pool_rules]
end
private
def safe_params
params.require(:ip_pool_rule).permit(:from_text, :to_text, :ip_pool_id)
end
end

عرض الملف

@@ -0,0 +1,9 @@
class IPPoolsController < ApplicationController
include WithinOrganization
def index
@ip_pools = organization.ip_pools.dedicated.order(:name)
end
end

عرض الملف

@@ -0,0 +1,226 @@
class MessagesController < ApplicationController
include WithinOrganization
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
before_action { params[:id] && @message = @server.message_db.message(params[:id].to_i) }
def new
if params[:direction] == 'incoming'
@message = IncomingMessagePrototype.new(@server, request.ip, 'web-ui', {})
@message.from = session[:test_in_from] || current_user.email_tag
@message.to = @server.routes.order(:name).first&.description
else
@message = OutgoingMessagePrototype.new(@server, request.ip, 'web-ui', {})
@message.to = session[:test_out_to] || current_user.email_address
if domain = @server.domains.verified.order(:name).first
@message.from = "test@#{domain.name}"
end
end
@message.subject = "Test Message at #{Time.now.to_s(:long)}"
@message.plain_body = "This is a message to test the delivery of messages through Postal."
end
def create
if params[:direction] == 'incoming'
session[:test_in_from] = params[:message][:from] if params[:message]
@message = IncomingMessagePrototype.new(@server, request.ip, 'web-ui', params[:message])
@message.attachments = [{:name => "test.txt", :content_type => "text/plain", :data => "Hello world!"}]
else
session[:test_out_to] = params[:message][:to] if params[:message]
@message = OutgoingMessagePrototype.new(@server, request.ip, 'web-ui', params[:message])
end
if result = @message.create_messages
if result.size == 1
redirect_to_with_json organization_server_message_path(organization, @server, result.first.last[:id]), :notice => "Message was queued successfully"
else
redirect_to_with_json [:queue, organization, @server], :notice => "Messages queued successfully "
end
else
respond_to do |wants|
wants.html do
flash.now[:alert] = "Your message could not be sent. Ensure that all fields are completed fully. #{result.errors.inspect}"
render 'new'
end
wants.json do
render :json => {:flash => {:alert => "Your message could not be sent. Please check all field are completed fully."}}
end
end
end
end
def outgoing
@searchable = true
get_messages('outgoing')
respond_to do |wants|
wants.html
wants.json { render :json => {
:flash => flash.each_with_object({}) { |(type, message), hash| hash[type] = message},
:region_html => render_to_string(:partial => 'index', :formats => [:html])
}}
end
end
def incoming
@searchable = true
get_messages('incoming')
respond_to do |wants|
wants.html
wants.json { render :json => {
:flash => flash.each_with_object({}) { |(type, message), hash| hash[type] = message},
:region_html => render_to_string(:partial => 'index', :formats => [:html])
}}
end
end
def held
get_messages('held')
end
def deliveries
render :json => {:html => render_to_string(:partial => 'deliveries', :locals => {:message => @message})}
end
def html_raw
render :html => @message.html_body_without_tracking_image.html_safe
end
def spam_checks
@spam_checks = @message.spam_checks.sort_by { |s| s['score']}.reverse
end
def attachment
if @message.attachments.size > params[:attachment].to_i
attachment = @message.attachments[params[:attachment].to_i]
send_data attachment.body, :content_type => attachment.mime_type, :disposition => 'download', :filename => attachment.filename
else
redirect_to attachments_organization_server_message_path(organization, @server, @message.id), :alert => "Attachment not found. Choose an attachment from the list below."
end
end
def download
if @message.raw_message
send_data @message.raw_message, :filename => "Message-#{organization.permalink}-#{@server.permalink}-#{@message.id}.eml", :content_type => "text/plain"
else
redirect_to organization_server_message_path(organization, @server, @message.id), :alert => "We no longer have the raw message stored for this message."
end
end
def retry
if @message.queued_message
@message.queued_message.queue!
flash[:notice] = "This message will be retried shortly."
elsif @message.held?
@message.add_to_message_queue(:manual => true)
flash[:notice] = "This message has been released. Delivery will be attempted shortly."
elsif @server.mode == 'Development'
@message.add_to_message_queue(:manual => true)
flash[:notice] = "This message will be redelivered shortly."
else
flash[:alert] = "This message is no longer queued for sending."
end
redirect_to_with_json organization_server_message_path(organization, @server, @message.id)
end
def cancel_hold
@message.cancel_hold
redirect_to_with_json organization_server_message_path(organization, @server, @message.id)
end
def remove_from_queue
if @message.queued_message && !@message.queued_message.locked?
@message.queued_message.destroy
end
redirect_to_with_json organization_server_message_path(organization, @server, @message.id)
end
def suppressions
@suppressions = @server.message_db.suppression_list.all_with_pagination(params[:page])
end
def activity
@entries = @message.activity_entries
end
private
def get_messages(scope)
if scope == 'held'
options = {:where => {:held => 1}}
else
options = {:where => {:scope => scope, :spam => false}, :order => :timestamp, :direction => 'desc'}
if @query = (params[:query] || session["msg_query_#{@server.id}_#{scope}"]).presence
session["msg_query_#{@server.id}_#{scope}"] = @query
qs = Postal::QueryString.new(@query)
if qs.empty?
flash.now[:alert] = "It doesn't appear you entered anything to filter on. Please double check your query."
else
@queried = true
if qs[:order] == 'oldest-first'
options[:direction] = 'asc'
end
options[:where][:rcpt_to] = qs[:to] if qs[:to]
options[:where][:mail_from] = qs[:from] if qs[:from]
options[:where][:status] = qs[:status] if qs[:status]
options[:where][:token] = qs[:token] if qs[:token]
if qs[:msgid]
options[:where][:message_id] = qs[:msgid]
options[:where].delete(:spam)
options[:where].delete(:scope)
end
options[:where][:tag] = qs[:tag] if qs[:tag]
options[:where][:id] = qs[:id] if qs[:id]
options[:where][:spam] = true if qs[:spam] == 'yes' || qs[:spam] == 'y'
if qs[:before] || qs[:after]
options[:where][:timestamp] = {}
if qs[:before]
begin
options[:where][:timestamp][:less_than] = get_time_from_string(qs[:before]).to_f
rescue TimeUndetermined => e
flash.now[:alert] = "Couldn't determine time for before from '#{qs[:before]}'"
end
end
if qs[:after]
begin
options[:where][:timestamp][:greater_than] = get_time_from_string(qs[:after]).to_f
rescue TimeUndetermined => e
flash.now[:alert] = "Couldn't determine time for after from '#{qs[:after]}'"
end
end
end
end
else
session["msg_query_#{@server.id}_#{scope}"] = nil
end
end
@messages = @server.message_db.messages_with_pagination(params[:page], options)
end
class TimeUndetermined < Postal::Error; end
def get_time_from_string(string)
begin
if string =~ /\A(\d{2,4})\-(\d{2})\-(\d{2}) (\d{2})\:(\d{2})\z/
time = Time.new($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i)
elsif string =~ /\A(\d{2,4})\-(\d{2})\-(\d{2})\z/
time = Time.new($1.to_i, $2.to_i, $3.to_i, 0)
else
time = Chronic.parse(string, :context => :past)
end
rescue
end
if time.nil?
raise TimeUndetermined, "Couldn't determine a suitable time from '#{string}'"
else
time
end
end
end

عرض الملف

@@ -0,0 +1,62 @@
class OrganizationsController < ApplicationController
before_action :require_organization_admin, :only => [:edit, :update, :delete, :destroy]
def index
@organizations = current_user.organizations.present.order(:name).to_a
if @organizations.size == 1 && params[:nrd].nil?
redirect_to organization_root_path(@organizations.first)
end
end
def new
@organization = Organization.new
end
def create
@organization = Organization.new(params.require(:organization).permit(:name, :permalink))
@organization.owner = current_user
if @organization.save
@organization.users << current_user
redirect_to_with_json organization_root_path(@organization)
else
render_form_errors 'new', @organization
end
end
def edit
@organization_obj = current_user.organizations_scope.find(organization.id)
end
def update
@organization_obj = current_user.organizations_scope.find(organization.id)
if @organization_obj.update(params.require(:organization).permit(:name, :time_zone))
redirect_to_with_json organization_settings_path(@organization_obj), :notice => "Settings for #{@organization_obj.name} have been saved successfully."
else
render_form_errors 'edit', @organization_obj
end
end
def destroy
unless current_user.authenticate(params[:password])
respond_to do |wants|
wants.html { redirect_to organization_delete_path(@organization), :alert => "The password you entered was not valid. Please check and try again." }
wants.json { render :json => {:alert => "The password you entered was invalid. Please check and try again."} }
end
return
end
organization.soft_destroy
redirect_to_with_json root_path(:nrd => 1), :notice => "#{@organization.name} has been removed successfully."
end
private
def organization
if [:edit, :update, :delete, :destroy].include?(action_name.to_sym)
@organization ||= params[:org_permalink] ? current_user.organizations_scope.find_by_permalink!(params[:org_permalink]) : nil
end
end
helper_method :organization
end

عرض الملف

@@ -0,0 +1,44 @@
class RoutesController < ApplicationController
include WithinOrganization
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
before_action { params[:id] && @route = @server.routes.find_by_uuid!(params[:id]) }
def index
@routes = @server.routes.order(:name).includes(:domain, :endpoint).to_a
end
def new
@route = @server.routes.build
end
def create
@route = @server.routes.build(safe_params)
if @route.save
redirect_to_with_json [organization, @server, :routes]
else
render_form_errors 'new', @route
end
end
def update
if @route.update(safe_params)
redirect_to_with_json [organization, @server, :routes]
else
render_form_errors 'edit', @route
end
end
def destroy
@route.destroy
redirect_to_with_json [organization, @server, :routes]
end
private
def safe_params
params.require(:route).permit(:name, :domain_id, :spam_mode, :_endpoint, :additional_route_endpoints_array => [])
end
end

عرض الملف

@@ -0,0 +1,90 @@
class ServersController < ApplicationController
include WithinOrganization
before_action :require_organization_admin, :only => [:new, :create, :delete, :destroy]
before_action :admin_required, :only => [:admin, :suspend, :unsuspend]
before_action { params[:id] && @server = organization.servers.present.find_by_permalink!(params[:id]) }
def index
@servers = organization.servers.present.order(:name).to_a
end
def show
if @server.created_at < 48.hours.ago
@graph_type = :daily
graph_data = @server.message_db.statistics.get(:daily, [:incoming, :outgoing, :bounces], Time.now, 30)
elsif @server.created_at < 24.hours.ago
@graph_type = :hourly
graph_data = @server.message_db.statistics.get(:hourly, [:incoming, :outgoing, :bounces], Time.now, 48)
else
@graph_type = :hourly
graph_data = @server.message_db.statistics.get(:hourly, [:incoming, :outgoing, :bounces], Time.now, 24)
end
@first_date = graph_data.first.first
@last_date = graph_data.last.first
@graph_data = graph_data.map(&:last)
@messages = @server.message_db.messages(:order => 'id', :direction => 'desc', :limit => 6)
end
def new
@server = organization.servers.build
end
def create
@server = organization.servers.build(safe_params(:permalink))
if @server.save
redirect_to_with_json organization_server_path(organization, @server)
else
render_form_errors 'new', @server
end
end
def update
extra_params = [:spam_threshold, :spam_failure_threshold, :postmaster_address]
extra_params += [:send_limit, :allow_sender, :log_smtp_data, :outbound_spam_threshold, :message_retention_days, :raw_message_retention_days, :raw_message_retention_size, :ip_pool_id] if current_user.admin?
if @server.update(safe_params(*extra_params))
redirect_to_with_json organization_server_path(organization, @server), :notice => "Server settings have been updated"
else
render_form_errors 'edit', @server
end
end
def destroy
unless current_user.authenticate(params[:password])
respond_to do |wants|
wants.html do
redirect_to [:delete, organization, @server], :alert => "The password you entered was not valid. Please check and try again."
end
wants.json do
render :json => {:alert => "The password you entere was invalid. Please check and try again"}
end
end
return
end
@server.soft_destroy
redirect_to_with_json organization_root_path(organization), :notice => "#{@server.name} has been deleted successfully"
end
def queue
@messages = @server.queued_messages.order(:id => :desc).page(params[:page])
@messages_with_message = @messages.include_message
end
def suspend
@server.suspend(params[:reason])
redirect_to_with_json [organization, @server], :notice => "Server has been suspended"
end
def unsuspend
@server.unsuspend
redirect_to_with_json [organization, @server], :notice => "Server has been unsuspended"
end
private
def safe_params(*extras)
params.require(:server).permit(:name, :mode, :ip_pool_id, *extras)
end
end

عرض الملف

@@ -0,0 +1,75 @@
class SessionsController < ApplicationController
layout 'sub'
skip_before_action :login_required, :only => [:new, :create, :create_with_token, :begin_password_reset, :finish_password_reset, :ip, :raise_error]
skip_before_action :verified_email_required
def create
login(User.authenticate(params[:email_address], params[:password]))
flash[:remember_login] = true
redirect_to_with_return_to root_path
rescue Postal::Errors::AuthenticationError => e
flash.now[:alert] = "The credentials you've provided are incorrect. Please check and try again."
render 'new'
end
def create_with_token
result = JWT.decode(params[:token], Postal.signing_key.to_s, 'HS256')[0]
if result['timestamp'] > 1.minute.ago.to_f
login(User.find(result['user'].to_i))
redirect_to root_path
else
destroy
end
rescue JWT::VerificationError
destroy
end
def destroy
auth_session.invalidate! if logged_in?
reset_session
redirect_to login_path
end
def persist
auth_session.persist! if logged_in?
render :plain => "OK"
end
def begin_password_reset
if request.post?
if user = User.where(:email_address => params[:email_address]).first
user.begin_password_reset(params[:return_to])
redirect_to login_path(:return_to => params[:return_to]), :notice => "Please check your e-mail and click the link in the e-mail we've sent you."
else
redirect_to login_reset_path(:return_to => params[:return_to]), :alert => "No user exists with that e-mail address. Please check and try again."
end
end
end
def finish_password_reset
@user = User.where(:password_reset_token => params[:token]).where("password_reset_token_valid_until > ?", Time.now).first
if @user.nil?
redirect_to login_path(:return_to => params[:return_to]), :alert => "This link has expired or never existed. Please choose reset password to try again."
end
if request.post?
if params[:password].blank?
flash.now[:alert] = "You must enter a new password"
return
end
@user.password = params[:password]
@user.password_confirmation = params[:password_confirmation]
if @user.save
login(@user)
redirect_to_with_return_to root_path, :notice => "Your new password has been set and you've been logged in."
end
end
end
def ip
render :plain => "ip: #{request.ip} remote ip: #{request.remote_ip}"
end
end

عرض الملف

@@ -0,0 +1,43 @@
class SMTPEndpointsController < ApplicationController
include WithinOrganization
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
before_action { params[:id] && @smtp_endpoint = @server.smtp_endpoints.find_by_uuid!(params[:id]) }
def index
@smtp_endpoints = @server.smtp_endpoints.order(:name).to_a
end
def new
@smtp_endpoint = @server.smtp_endpoints.build
end
def create
@smtp_endpoint = @server.smtp_endpoints.build(safe_params)
if @smtp_endpoint.save
flash[:notice] = params[:return_notice] if params[:return_notice].present?
redirect_to_with_json [:return_to, [organization, @server, :smtp_endpoints]]
else
render_form_errors 'new', @smtp_endpoint
end
end
def update
if @smtp_endpoint.update(safe_params)
redirect_to_with_json [organization, @server, :smtp_endpoints]
else
render_form_errors 'edit', @smtp_endpoint
end
end
def destroy
@smtp_endpoint.destroy
redirect_to_with_json [organization, @server, :smtp_endpoints]
end
private
def safe_params
params.require(:smtp_endpoint).permit(:name, :hostname, :port, :ssl_mode)
end
end

عرض الملف

@@ -0,0 +1,49 @@
class TrackDomainsController < ApplicationController
include WithinOrganization
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
before_action { params[:id] && @track_domain = @server.track_domains.find_by_uuid!(params[:id]) }
def index
@track_domains = @server.track_domains.order(:name).to_a
end
def new
@track_domain = @server.track_domains.build
end
def create
@track_domain = @server.track_domains.build(params.require(:track_domain).permit(:name, :domain_id, :track_loads, :track_clicks, :excluded_click_domains, :ssl_enabled))
if @track_domain.save
redirect_to_with_json [:return_to, [organization, @server, :track_domains]]
else
render_form_errors 'new', @track_domain
end
end
def update
if @track_domain.update(params.require(:track_domain).permit(:track_loads, :track_clicks, :excluded_click_domains, :ssl_enabled))
redirect_to_with_json [organization, @server, :track_domains]
else
render_form_errors 'edit', @track_domain
end
end
def destroy
@track_domain.destroy
redirect_to_with_json [organization, @server, :track_domains]
end
def check
if @track_domain.check_dns
redirect_to_with_json [organization, @server, :track_domains], :notice => "Your CNAME for #{@track_domain.full_name} looks good!"
else
redirect_to_with_json [organization, @server, :track_domains], :alert => "There seems to be something wrong with your DNS record. Check documentation for information."
end
end
def toggle_ssl
@track_domain.update(:ssl_enabled => !@track_domain.ssl_enabled)
redirect_to_with_json [organization, @server, :track_domains], :notice => "SSL settings for #{@track_domain.full_name} updated successfully."
end
end

عرض الملف

@@ -0,0 +1,85 @@
class UserController < ApplicationController
skip_before_action :login_required, :only => [:new, :create]
skip_before_action :verified_email_required, :only => [:edit, :update, :verify]
def new
@user = User.new
render :layout => 'sub'
end
def create
@user = User.new(params.require(:user).permit(:first_name, :last_name, :email_address, :password, :password_confirmation))
if @user.save
AppMailer.new_user(@user).deliver
self.current_user = @user
redirect_to verify_path(:return_to => params[:return_to])
else
render 'new', :layout => 'sub'
end
end
def join
if @invite = UserInvite.where(:uuid => params[:token]).where("expires_at > ?", Time.now).first
if request.post?
@invite.accept(current_user)
redirect_to_with_json root_path(:nrd => 1), :notice => "Invitation has been accepted successfully. You now have access to this organization."
elsif request.delete?
@invite.reject
redirect_to_with_json root_path(:nrd => 1), :notice => "Invitation has been rejected successfully."
else
@organizations = @invite.organizations.order(:name).to_a
end
else
redirect_to_with_json root_path(:nrd => 1), :alert => "The invite URL you have has expired. Please ask the person who invited you to re-send your invitation."
end
end
def edit
@user = User.find(current_user.id)
end
def update
@user = User.find(current_user.id)
@user.attributes = params.require(:user).permit(:first_name, :last_name, :time_zone, :email_address, :password, :password_confirmation)
if @user.authenticate_with_previous_password_first(params[:password])
@password_correct = true
else
respond_to do |wants|
wants.html do
flash.now[:alert] = "The current password you have entered is incorrect. Please check and try again."
render 'edit'
end
wants.json do
render :json => {:alert => "The current password you've entered is incorrect. Please check and try again"}
end
end
return
end
email_changed = @user.email_address_changed?
if @user.save
if email_changed
redirect_to_with_json verify_path(:return_to => settings_path), :notice => "Your settings have been updated successfully. As you've changed, your e-mail address you'll need to verify it before you can continue."
else
redirect_to_with_json settings_path, :notice => "Your settings have been updated successfully."
end
else
render_form_errors 'edit', @user
end
end
def verify
if request.post?
if params[:code].to_s.strip == current_user.email_verification_token.to_s || (Rails.env.development? && params[:code].to_s.strip == "123456")
current_user.verify!
redirect_to_with_json [:return_to, root_path], :notice => "Thanks - your e-mail address has been verified successfully."
else
flash_now :alert, "The code you've entered isn't correct. Please check and try again."
end
end
end
end

عرض الملف

@@ -0,0 +1,63 @@
class UsersController < ApplicationController
include WithinOrganization
before_action :require_organization_admin
before_action :require_organization_owner, :only => [:make_owner]
before_action { params[:id] && @user = params[:invite] ? organization.user_invites.find_by_uuid!(params[:id]) : organization.users.find_by_uuid!(params[:id]) }
def index
@users = organization.organization_users.where(:user_type => 'User').includes(:user).to_a.sort_by { |u| "#{u.user.first_name}#{u.user.last_name}".upcase }
@pending_users = organization.organization_users.where(:user_type => "UserInvite").includes(:user).to_a.sort_by { |u| u.user.email_address.upcase }
end
def new
@organization_user = organization.organization_users.build
end
def create
@organization_user = organization.organization_users.build(params.require(:organization_user).permit(:email_address, :admin, :all_servers))
if @organization_user.save
AppMailer.user_invite(@organization_user.user, organization).deliver
redirect_to_with_json [organization, :users], :notice => "An invitation will be sent to #{@organization_user.user.email_address} which will allow them to access your organization."
else
render_form_errors 'new', @organization_user
end
end
def edit
@organization_user = organization.user_assignment(@user)
end
def update
@organization_user = organization.user_assignment(@user)
if @organization_user.update(params.require(:organization_user).permit(:admin))
redirect_to_with_json [organization, :users], :notice => "Permissions for #{@organization_user.user.name} have been updated successfully."
else
render_form_errors 'edit', @organization_user
end
end
def destroy
if @user == current_user
redirect_to_with_json [organization, :users], :alert => "You cannot revoke your own access."
return
end
if @user == organization.owner
redirect_to_with_json [organization, :users], :alert => "You cannot revoke the organization owner's access."
return
end
organization.organization_users.where(:user => @user).destroy_all
redirect_to_with_json [organization, :users], :notice => "#{@user.name} has been removed from this organization"
end
def make_owner
if @user.is_a?(User)
organization.make_owner(@user)
redirect_to_with_json [organization, :users], :notice => "#{@user.name} is now the owner of this organization."
else
raise Postal::Error, "User must be a User not a UserInvite to make owner"
end
end
end

عرض الملف

@@ -0,0 +1,51 @@
class WebhooksController < ApplicationController
include WithinOrganization
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
before_action { params[:id] && @webhook = @server.webhooks.find_by_uuid!(params[:id]) }
def index
@webhooks = @server.webhooks.order(:url).to_a
end
def new
@webhook = @server.webhooks.build(:all_events => true)
end
def create
@webhook = @server.webhooks.build(safe_params)
if @webhook.save
redirect_to_with_json [organization, @server, :webhooks]
else
render_form_errors 'new', @webhook
end
end
def update
if @webhook.update(safe_params)
redirect_to_with_json [organization, @server, :webhooks]
else
render_form_errors 'edit', @webhook
end
end
def destroy
@webhook.destroy
redirect_to_with_json [organization, @server, :webhooks]
end
def history
@current_page = params[:page] ? params[:page].to_i : 1
@requests = @server.message_db.webhooks.list(@current_page)
end
def history_request
@req = @server.message_db.webhooks.find(params[:uuid])
end
private
def safe_params
params.require(:webhook).permit(:name, :url, :all_events, :enabled, :events => [])
end
end