centrifugal/centrifuge-ruby

View on GitHub
lib/cent/notary.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true

require 'jwt'
require 'cent/error'

module Cent
  # Cent::Notary
  #
  #   Handle token generation
  #
  class Notary
    # @param secret [String | OpenSSL::PKey::RSA | OpenSSL::PKey::EC] Secret key for the algorithm of your choice.
    # @param algorithm [String] Specify algorithm(one from HMAC, RSA or ECDSA family). Default is HS256.
    #
    # @example Construct new client instance
    #   notary = Cent::Notary.new(secret: 'secret')
    #
    def initialize(secret:, algorithm: 'HS256')
      raise Error, 'Secret can not be nil' if secret.nil?

      @secret = secret
      @algorithm = algorithm
    end

    # Generate connection JWT for the given user
    #
    # @param sub [String]
    #   Standard JWT claim which must contain an ID of current application user.
    #
    # @option channel [String]
    #   Channel that client tries to subscribe to (string).
    #
    # @param exp [Integer]
    #   (default: nil) UNIX timestamp seconds when token will expire.
    #
    # @param info [Hash]
    #   (default: {}) This claim is optional - this is additional information about
    #   client connection that can be provided for Centrifugo.
    #
    # @example Get user JWT with expiration and extra info
    #   notary.issue_connection_token(sub: '1', exp: 3600, info: { 'role' => 'admin' })
    #     #=> "eyJhbGciOiJIUzI1NiJ9.eyJzdWIi..."
    #
    # @see (https://centrifugal.github.io/centrifugo/server/authentication/)
    #
    # @return [String]
    #
    def issue_connection_token(sub:, info: nil, exp: nil)
      payload = {
        'sub' => sub,
        'info' => info,
        'exp' => exp
      }.compact

      JWT.encode(payload, secret, algorithm)
    end

    # Generate JWT for private channels
    #
    # @param client [String]
    #   Client ID which wants to subscribe on channel
    #
    # @option channel [String]
    #   Channel that client tries to subscribe to (string).
    #
    # @param exp [Integer]
    #   (default: nil) UNIX timestamp seconds when token will expire.
    #
    # @param info [Hash]
    #   (default: {}) This claim is optional - this is additional information about
    #   client connection that can be provided for Centrifugo.
    #
    # @example Get private channel JWT with expiration and extra info
    #   notary.issue_channel_token(client: 'client', channel: 'channel', exp: 3600, info: { 'message' => 'wat' })
    #     #=> eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnQiOiJjbG..."
    #
    # @see (https://centrifugal.github.io/centrifugo/server/private_channels/)
    #
    # @return [String]
    #
    def issue_channel_token(client:, channel:, info: nil, exp: nil)
      payload = {
        'client' => client,
        'channel' => channel,
        'info' => info,
        'exp' => exp
      }.compact

      JWT.encode(payload, secret, algorithm)
    end

    private

    attr_reader :secret, :algorithm
  end
end