Thursday, 9 January 2020

Authentication on jwt

Okay now we’re ready to generate rails project, type this on your terminal
$ rails new rails-jwt --api
Add Json Web Token (JWT) and bcrypt gem
  • JWT : Token encoder / decoder with expiration time
  • bcrypt : Password encryption
# Use Json Web Token (JWT) for token based authenticationgem 'jwt'
# Use ActiveModel has_secure_passwordgem 'bcrypt', '~> 3.1.7'
and then install dependencies by typing this on your terminal
$ bundle install
# config/routes.rbRails.application.routes.draw resources :users, param: :_username
  post '/auth/login', to: 'authentication#login'
  get '/*a', to: 'application#not_found'
======================================================================
Add new file: app/lib/json_web_token.rb

class JsonWebToken
SECRET_KEY = Rails.application.secrets.secret_key_base. to_s
def self.encode(payload, exp = 24.hours.from_now)
payload[:exp] = exp.to_i
JWT.encode(payload, SECRET_KEY)
end
def self.decode(token)
decoded = JWT.decode(token, SECRET_KEY)[0]
HashWithIndifferentAccess.new decoded
end
end
=======================================================================
For Application controller:

class ApplicationController < ActionController::API
def not_found
    render json: { error: 'not_found' }
  end

  def authorize_request
    header = request.headers['Token']
    header = header.split(' ').last if header
    begin
      @decoded = JsonWebToken.decode(header)
      @current_user = User.find(@decoded[:user_id])
    rescue ActiveRecord::RecordNotFound => e
      render json: { errors: e.message }, status: :unauthorized
    rescue JWT::DecodeError => e
      render json: { errors: e.message }, status: :unauthorized
    end
  end
end
=====================================================================
Create user model
$ rails g model user name:string username:string email:string password_digest:string
===================================================================
Add user.rb:

class User < ApplicationRecord
has_secure_password
mount_uploader :avatar, AvatarUploader
validates :email, presence: true, uniqueness: true
validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :username, presence: true, uniqueness: true
validates :password,
length: { minimum: 6 },
if: -> { new_record? || !password.nil? }
end
========================================================================
$ rails g controller users

class UsersController < ApplicationController
  before_action :authorize_request, except: :create
  before_action :find_user, except: %i[create index]

  # GET /users
  def index
    @users = User.all
    render json: @users, status: :ok
  end

  # GET /users/{username}
  def show
    render json: @user, status: :ok
  end

  # POST /users
  def create
    @user = User.new(user_params)
    if @user.save
      render json: @user, status: :created
    else
      render json: { errors: @user.errors.full_messages },
             status: :unprocessable_entity
    end
  end

  # PUT /users/{username}
  def update
    unless @user.update(user_params)
      render json: { errors: @user.errors.full_messages },
             status: :unprocessable_entity
    end
  end

  # DELETE /users/{username}
  def destroy
    @user.destroy
  end

  private

  def find_user
    @user = User.find_by_username!(params[:_username])
    rescue ActiveRecord::RecordNotFound
      render json: { errors: 'User not found' }, status: :not_found
  end

  def user_params
    params.permit(
      :avatar, :name, :username, :email, :password, :password_confirmation
    )
  end
end
======================================================================

Create authentication controller
$ rails g controller authentication

before_action :authorize_request, except: :login
# POST /auth/login
def login
@user = User.find_by_email(params[:email])
if @user&.authenticate(params[:password])
token = JsonWebToken.encode(user_id: @user.id)
time = Time.now + 24.hours.to_i
render json: { token: token, exp: time.strftime("%m-%d-%Y %H:%M"),
username: @user.username }, status: :ok
else
render json: { error: 'unauthorized' }, status: :unauthorized
end
end
private
def login_params
params.permit(:email, :password)
end

=======================================================================
Add a app/config/application.rb

load_path_strategy = Rails.env.production? ? :eager_load_paths : :autoload_paths
    config.public_send(load_path_strategy) << Rails.root.join('lib')














































Thursday, 26 December 2019

File upload on carrierwave S3


gem 'mini_magick'
gem "carrierwave"
gem 'fog'
gem "fog-aws"

==================================

Uploader on:

storage :fog

==================================

For this Storage on AWS With Fog


config/initializers/carrierwave.rb


CarrierWave.configure do |config|
  if Rails.env.development? || Rails.env.test?
    config.storage = :fog
  else   
    config.fog_provider = 'fog/aws'

    config.fog_credentials = {
      :provider               => 'AWS',       # required
      :aws_access_key_id      => ENV['AWS_ACCESS_KEY_ID'], # required
      :aws_secret_access_key  => ENV['AWS_SECRET_ACCESS_KEY'],  # required
      :region                 => ENV['REGION'], # optional, defaults to 'us-east-1'
      :endpoint               => "https://s3-#{ENV['REGION']}.amazonaws.com"
    }
    config.fog_directory  = ENV['AWS_BUCKET_NAME'] # required
    # config.fog_public     = false 
    config.fog_attributes = { :cache_control => 'max-age=315576000', :expires => 1.year.from_now.httpdate }
    # see https://github.com/jnicklas/carrierwave#using-amazon-s3
    # for more optional configuration
  end
end


=============================================================

For Storage on AWS


Add gem: gem 'aws-sdk'

On uploader file: storage :aws



CarrierWave.configure do |config|
  config.storage    = :aws
  config.aws_bucket = ENV['S3_BUCKET_NAME']
  config.aws_acl    = 'public-read'
  config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7
  config.aws_credentials = {
    access_key_id:     ENV['AWS_ACCESS_KEY_ID'],
    secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
    region:            ENV['AWS_REGION'] # Required
  }
  config.asset_host = ENV['CLOUDFRONT_ENDPOINT']
end


============================================================

development:
 
  AWS_SECRET_ACCESS_KEY: xxxxxxxxxxxxxxxxxxxx
  AWS_ACCESS_KEY_ID: xxxxxxxxxxxxxxxxxxxx
  REGION: xxxxxxxx
  AWS_BUCKET_NAME: xxxxxxx.xxx
production:
  # Database
 
  AWS_SECRET_ACCESS_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxx
  AWS_ACCESS_KEY_ID: xxxxxxxxxxxxxxxx
  REGION: uxxxxxxx
  AWS_BUCKET_NAME: xxxxxxxx.xxx

Thursday, 19 December 2019

Multiple show image preview before Upload for Carrierwave

https://stackoverflow.com/questions/43729171/how-to-show-image-preview-before-upload



gem 'jquery-ui-rails'
gem "jquery-rails"
gem 'carrierwave'


//= require jquery





On controller


def create
   

    if params[:master][:image].present?
      params[:master][:image].each do |img|
        @master = Master.new(image: img)
        @master.save
      end
    end
    redirect_to masters_path, notice: 'Master was successfully created.'
  end















===============================================
ON form

remove title or description







<%= form_with(model: master, local: true) do |form| %>
  <% if master.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(master.errors.count, "error") %> prohibited this master from being saved:</h2>

      <ul>
      <% master.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>

  <div class="field">
    <%= form.label :description %>
    <%= form.text_area :description %>
  </div>

  <div class="field">
    <%= form.label :image %>
    <%= form.file_field :image, id: "uploadBtn", :multiple => true, style: "display: none !important;" %>
    <input type="button" value="Choose File" onclick="document.getElementById('uploadBtn').click();" />

  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
 

<input id="filename" type="hidden" />
<br>
<div id="upload_prev"></div>
<% end %>




<script type="text/javascript">
  $(document).on('click', '.close', function() {
  $(this).siblings("img").toggle();
})

document.getElementById("uploadBtn").onchange = function() {
  document.getElementById("uploadFile").value = this.value;
};

document.getElementById('uploadBtn').onchange = uploadOnChange;

function uploadOnChange() {
  var filename = this.value;
  var lastIndex = filename.lastIndexOf("\\");
  if (lastIndex >= 0) {
    filename = filename.substring(lastIndex + 1);
  }
  var files = $('#uploadBtn')[0].files;
  for (var i = 0; i < files.length; i++) {
    (function(i) {
      $("#upload_prev").append('<div><br><div class="col-md-10"><span class="uploadFiles">' + '<a href="">' + files[i].name + '</a>' + '</span></div><div class="col-md-2"><p class="close" style="font-size: 13pt;">削除</p><br></div></div>');
      $("#upload_prev a:contains(" + files[i].name + ")")
        .on("click", function(e) {
          e.preventDefault();
          var close = $(this).closest("div")
            .next("div")
            .find(".close");
          if (!$(this).closest("div")
            .next("div").find("img").length)
            close
            .after(
              $("<img>", {
                src: URL.createObjectURL(files[i])
              })
            )
          else
            close.siblings("img").toggle()
        })
    })(i);
  }

  document.getElementById('filename').value = filename;
}
</script>


==================================================================



https://stackoverflow.com/questions/14069421/show-an-image-preview-before-upload



<%= form_with(model: master, local: true) do |form| %>
  <% if master.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(master.errors.count, "error") %> prohibited this master from being saved:</h2>

      <ul>
      <% master.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>

  <div class="field">
    <%= form.label :description %>
    <%= form.text_area :description %>
  </div>

  <div class="field">
    <%= form.label :image %>
    <%= form.file_field :image, id: "fileUpload", :multiple => true %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
  <!-- <input id="fileUpload" type="file" multiple /> -->
  <div id="image-holder"></div>
<% end %>


<script type="text/javascript">
  $("#fileUpload").on('change', function () {

     //Get count of selected files
     var countFiles = $(this)[0].files.length;

     var imgPath = $(this)[0].value;
     var extn = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase();
     var image_holder = $("#image-holder");
     image_holder.empty();

     if (extn == "gif" || extn == "png" || extn == "jpg" || extn == "jpeg") {
         if (typeof (FileReader) != "undefined") {

             //loop for each file selected for uploaded.
             for (var i = 0; i < countFiles; i++) {

                 var reader = new FileReader();
                 reader.onload = function (e) {
                     $("<img />", {
                         "src": e.target.result,
                             "class": "thumb-image"
                     }).appendTo(image_holder);
                 }

                 image_holder.show();
                 reader.readAsDataURL($(this)[0].files[i]);
             }

         } else {
             alert("This browser does not support FileReader.");
         }
     } else {
         alert("Pls select only images");
     }
 });
</script>

Thursday, 8 August 2019

Top count in views



@tabs = Tab.select("tabs.*, COUNT(views.id) something_variable").joins(:views).where('views.created_at between ? and ?', Time.now - 1.week, Time.now).group("tabs.id").order("something_variable DESC").paginate(page: page,per_page: 200)

Saturday, 16 February 2019

Count Down time

//= require jquery.countdown for application.js

Download jQuery.countdown.zip

=========================================

Html: haml this code

@aaaaaa.each_with_index do |Object, index|

%p{:id => "counter_#{Object.id}_#{Object.class.name}", class: "counter_time", "data-index": index, "data-id": Object.id, "data-time": (Object.end_date rescue Time.now - 1.days )}


====================================

js:

:javascript

  $(function(){
   
    var date = #{raw (Time.now + 8.days).to_i*1000}

    $(".counter_time").countdown(date, function(event) {

      var time = $(this).attr("data-time");
     
      var countDownDate = moment(time);

      var now = new Date().getTime();
      var time_in_number = new Date(time).getTime();

      var distance = countDownDate - now;

      var days = Math.floor(distance / (1000 * 60 * 60 * 24));
      var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
      var seconds = Math.floor((distance % (1000 * 60)) / 1000);

      if (days < 1)
        days = 0
     
      if (hours < 1)
        hours = 0
     
      if (minutes < 1)
        minutes = 0
     
      if (seconds < 1)
        seconds = 0
     
      var Dcount = "";
      if (days > 1)
        Dcount = " Days | "
      else
        Dcount = " Day | "
     
      var Hcount = ""
      if (hours > 1)
        Hcount = " Hours | "
      else
        Hcount = " Hour | "
     
      var Mcount = ""
      if (minutes > 1)
        Mcount = " Mins | "
      else
        Mcount = " Min | "
     
      var Scount = ""
      if (seconds > 1)
        Scount = " Secs "
      else
        Scount = " Sec "

      if (time === undefined)       
        $(this).html(" ");
      else if (time_in_number < now)
        $(this).html("Already Closed");
      else
        $(this).html(event.strftime(days + Dcount + hours + Hcount + minutes + Mcount + seconds + Scount));

    });
  });







Tuesday, 15 January 2019

Gem uninstall bundler version And install version

$ gem list bundle

bundler (2.0.1)
bundler-audit (0.6.0)
bundler-unload (1.0.2)
rubygems-bundler (1.4.4)

----------------------------------------------------------------------------

$ gem uninstall bundler -v '2.0.1'

ERROR:  While executing gem ... (Gem::InstallError)
    bundler is not installed in GEM_HOME, try:
gem uninstall -i /home/bittern-i5-3/.rvm/gems/ruby-2.4.1@global bundler

-----------------------------------------------------------------------------
 $ gem uninstall -i /home/bittern-i5-3/.rvm/gems/ruby-2.4.1@global bundler
-----------------------------------------------------------------------------
$ gem install bundler -v '~>1.17.1'



https://dev.to/st0012/completely-remove-the-default-bundler-from-ci-environment-j0c

Wednesday, 5 December 2018

switch user -- users list click any user for session create

Please visit the above doc :

https://github.com/flyerhzm/switch_user
======================================

Add Gem:

gem "switch_user"
=======================================
If you need to override the default configuration, run rails g switch_user:install and a copy of the configuration file will be copied to config/initializers/switch_user.rb in your project.

rails g switch_user:install

===========================================

Add file for controller:

app/controllers/switch_user_controller.rb

class SwitchUserController < ApplicationController
  def set_current_user
  user = User.find(params[:scope_identifier])
                # without devise
  if user.present?
  session[:user_id] = user.id
  redirect_to '/'
  end
                # with devise 
  # sign_in(user)
  end

  def remember_user
  end

end

==============================================

config/routes.rb

get 'switch_user', to: 'switch_user#set_current_user'

  get 'switch_user/remember_user', to: 'switch_user#remember_user'


=============================================

Add Link for Button:

1. Activeadmin Users index page
   
     column "Switch User" do |show|
        links = link_to 'Login As', "/switch_user?scope_identifier=#{show.id}"
     end

2. simple rails users index
   
    <%= link_to 'Login As', "/switch_user?scope_identifier=#{user.id}"%>
==============================================