soketi icon indicating copy to clipboard operation
soketi copied to clipboard

[BUG] Channel authorization fails when data is not provided

Open joaomlneto opened this issue 1 year ago • 2 comments

Description When a user attempts to subscribe to a presence channel, If the backend calls Pusher.authorizeChannel(socketId, channel, data?) without specifying the data optional parameter, the subscription will hang — no message will be logged on client/Soketi.

Reproduction steps See https://github.com/joaomlneto/soketi-error

If one changes the authorizeChannel call to pusher.authorizeChannel(socket_id, channel_name);, the channel subscription procedure will hang.

Expected behavior The channel subscription should succeed — this is what happens with Pusher Channels.

Environment

  • Soketi version: 1.5.0
  • Adapter: local
  • App Manager: array
  • Queue: sync
  • Cache Managers: memory

Configuration

{
  adapter: {
    driver: 'local',
    redis: {
      requestsTimeout: 5000,
      prefix: '',
      redisPubOptions: {},
      redisSubOptions: {},
      clusterMode: false
    },
    cluster: { requestsTimeout: 5000 },
    nats: {
      requestsTimeout: 5000,
      prefix: '',
      servers: [ '127.0.0.1:4222' ],
      user: null,
      pass: null,
      token: null,
      timeout: 10000,
      nodesNumber: null
    }
  },
  appManager: {
    driver: 'array',
    cache: { enabled: false, ttl: -1 },
    array: {
      apps: [
        {
          id: 'myapp',
          key: 'myapp-key',
          secret: 'myapp-secret',
          enabled: true,
          enableClientMessages: true,
          webhooks: [
            {
              url: 'http://localhost:4000/webhook',
              event_types: [
                'client_event',
                'channel_occupied',
                'channel_vacated',
                'member_added',
                'member_removed'
              ]
            }
          ]
        }
      ]
    },
    dynamodb: { table: 'apps', region: 'us-east-1', endpoint: null },
    mysql: { table: 'apps', version: '8.0', useMysql2: false },
    postgres: { table: 'apps', version: '13.3' }
  },
  cache: { driver: 'memory', redis: { redisOptions: {}, clusterMode: false } },
  channelLimits: { maxNameLength: 200, cacheTtl: 3600 },
  cluster: {
    hostname: '0.0.0.0',
    helloInterval: 500,
    checkInterval: 500,
    nodeTimeout: 2000,
    masterTimeout: 2000,
    port: 11002,
    prefix: '',
    ignoreProcess: true,
    broadcast: '255.255.255.255',
    unicast: null,
    multicast: null
  },
  cors: {
    credentials: true,
    origin: [ '*' ],
    methods: [ 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS' ],
    allowedHeaders: [
      'Origin',
      'Content-Type',
      'X-Auth-Token',
      'X-Requested-With',
      'Accept',
      'Authorization',
      'X-CSRF-TOKEN',
      'XSRF-TOKEN',
      'X-Socket-Id'
    ]
  },
  database: {
    mysql: {
      host: '127.0.0.1',
      port: 3306,
      user: 'root',
      password: 'password',
      database: 'main'
    },
    postgres: {
      host: '127.0.0.1',
      port: 5432,
      user: 'postgres',
      password: 'password',
      database: 'main'
    },
    redis: {
      host: '127.0.0.1',
      port: 6379,
      db: 0,
      username: null,
      password: null,
      keyPrefix: '',
      sentinels: null,
      sentinelPassword: null,
      name: 'mymaster',
      clusterNodes: []
    }
  },
  databasePooling: { enabled: false, min: 0, max: 7 },
  debug: true,
  eventLimits: {
    maxChannelsAtOnce: 100,
    maxNameLength: 200,
    maxPayloadInKb: 100,
    maxBatchSize: 10
  },
  host: '0.0.0.0',
  httpApi: { requestLimitInMb: 100, acceptTraffic: { memoryThreshold: 85 } },
  instance: { process_id: 55734 },
  metrics: {
    enabled: false,
    driver: 'prometheus',
    host: '0.0.0.0',
    prometheus: { prefix: 'soketi_' },
    port: 9601
  },
  mode: 'full',
  port: 6001,
  pathPrefix: '',
  presence: { maxMembersPerChannel: 100, maxMemberSizeInKb: 2 },
  queue: {
    driver: 'sync',
    redis: { concurrency: 1, redisOptions: {}, clusterMode: false },
    sqs: {
      region: 'us-east-1',
      endpoint: null,
      clientOptions: {},
      consumerOptions: {},
      queueUrl: '',
      processBatch: false,
      batchSize: 1,
      pollingWaitTimeMs: 0
    }
  },
  rateLimiter: { driver: 'local', redis: { redisOptions: {}, clusterMode: false } },
  shutdownGracePeriod: 3000,
  ssl: { certPath: '', keyPath: '', passphrase: '', caPath: '' },
  userAuthenticationTimeout: 3000,
  webhooks: { batching: { enabled: false, duration: 50 } }
}

joaomlneto avatar Mar 10 '23 12:03 joaomlneto

Hey Joaomlneto,

I recently faced the same issue/misunderstanding with the official Pusher Server.

For a user to subscribe to a presence channel the authorizeChannel must include the presenceData (in your case data). Read more about it here

As the Soketi incorporates the use of Pusher SDK, it looks like most of the behind the scenes working are the same.

MehulZR avatar Apr 06 '23 16:04 MehulZR

@rennokki Can you share the document on how I can create an app id and secret key for Soketi?

vivekkotadiya avatar Oct 27 '23 15:10 vivekkotadiya