Skip to content

Commit

Permalink
Merge pull request #20 from pusher/custom-authorizer
Browse files Browse the repository at this point in the history
add custom authorizer example
  • Loading branch information
fbenevides authored Jul 21, 2022
2 parents a0a70c3 + 669b4dc commit b2f077b
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 14 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.0.2

* [CHANGED] Use latest pusher websocket java sdk.
* [ADDED] Example to use a custom authorizer.

## 1.0.1

* [ADDED] Add onAuthorizer support to iOS
Expand Down
6 changes: 3 additions & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ buildscript {
repositories {
google()
mavenCentral()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:7.1.3'
classpath 'com.android.tools.build:gradle:7.2.0'
// noinspection DifferentKotlinGradleVersion
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
Expand Down Expand Up @@ -124,5 +123,6 @@ dependencies {
// noinspection GradleDynamicVersion
api 'com.facebook.react:react-native:+'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
api 'com.pusher:pusher-java-client:2.2.8'
api 'com.pusher:pusher-java-client:2.+'
api 'com.google.code.gson:gson:2.+'
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,23 @@ import android.util.Log
import com.facebook.react.bridge.*
import com.facebook.react.modules.core.DeviceEventManagerModule
import com.google.gson.Gson
import com.pusher.client.Authorizer
import com.pusher.client.ChannelAuthorizer
import com.pusher.client.Pusher
import com.pusher.client.PusherOptions
import com.pusher.client.channel.*
import com.pusher.client.connection.ConnectionEventListener
import com.pusher.client.connection.ConnectionState
import com.pusher.client.connection.ConnectionStateChange
import com.pusher.client.util.HttpAuthorizer
import com.pusher.client.util.HttpChannelAuthorizer
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.concurrent.Semaphore


class PusherWebsocketReactNativeModule(reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext),
ConnectionEventListener, ChannelEventListener, SubscriptionEventListener,
PrivateChannelEventListener, PrivateEncryptedChannelEventListener, PresenceChannelEventListener,
Authorizer {
ChannelAuthorizer {

private var pusher: Pusher? = null
private val TAG = "PusherReactNative"
Expand Down Expand Up @@ -73,9 +72,10 @@ class PusherWebsocketReactNativeModule(reactContext: ReactApplicationContext) :
arguments.getInt("maxReconnectionAttempts")
if (arguments.hasKey("maxReconnectGapInSeconds")) options.maxReconnectGapInSeconds =
arguments.getInt("maxReconnectGapInSeconds")
if (arguments.hasKey("authEndpoint")) options.authorizer =
HttpAuthorizer(arguments.getString("authEndpoint"))
if (arguments.hasKey("authorizer") && arguments.getBoolean("authorizer")) options.authorizer = this
if (arguments.hasKey("authEndpoint")) options.channelAuthorizer =
HttpChannelAuthorizer(arguments.getString("authEndpoint"))
if (arguments.hasKey("authorizer") && arguments.getBoolean("authorizer")) options.channelAuthorizer =
this
if (arguments.hasKey("proxy")) {
val (host, port) = arguments.getString("proxy")!!.split(':')
options.proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port.toInt()))
Expand Down Expand Up @@ -130,7 +130,8 @@ class PusherWebsocketReactNativeModule(reactContext: ReactApplicationContext) :
try {
when {
channelName.startsWith("private-encrypted-") -> throw Exception("It's not currently possible to send a message using private encrypted channels.")
channelName.startsWith("private-") -> pusher!!.getPrivateChannel(channelName).trigger(eventName, data)
channelName.startsWith("private-") -> pusher!!.getPrivateChannel(channelName)
.trigger(eventName, data)
channelName.startsWith("presence-") -> pusher!!.getPresenceChannel(channelName)
.trigger(eventName, data)
else -> throw Exception("Messages can only be sent to private and presence channels.")
Expand Down
1 change: 1 addition & 0 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"dependencies": {
"@react-native-async-storage/async-storage": "^1.17.5",
"crypto-es": "^1.2.7",
"react": "17.0.2",
"react-native": "0.68.2"
},
Expand Down
33 changes: 31 additions & 2 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
FlatList,
} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import CryptoES from 'crypto-es';
import { Pusher, PusherMember, PusherChannel, PusherEvent } from '../../src'; // This links the example app to the current SDK implementation

export default function App() {
Expand All @@ -22,7 +23,7 @@ export default function App() {
const [channelName, onChangeChannelName] = React.useState('');
const [eventName, onChangeEventName] = React.useState('');
const [eventData, onChangeEventData] = React.useState('');
const [members, onChangeMembers] = React.useState(new Array<PusherMember>());
const [members, onChangeMembers] = React.useState<PusherMember[]>([]);
const [logText, setLog] = React.useState('');

const log = async (line: string) => {
Expand Down Expand Up @@ -54,7 +55,21 @@ export default function App() {
await pusher.init({
apiKey,
cluster,
// authEndpoint: '<Add your Auth Endpoint here>',
// authEndpoint
// ============
// You can let the pusher library call an endpoint URL,
// Please look here to implement a server side authorizer:
// https://pusher.com/docs/channels/server_api/authenticating-users/
//
// authEndpoint: '<Add your Auth Endpoint URL here>',
//
// onAuthorizer
// ============
// Or you can implement your own authorizer callback.
// See https://pusher.com/docs/channels/library_auth_reference/auth-signatures/
// for the format of this object, you need your key and secret from your Pusher
// Account.
onAuthorizer,
onConnectionStateChange,
onError,
onEvent,
Expand Down Expand Up @@ -123,6 +138,20 @@ export default function App() {
onChangeMembers([...channel.members.values()]);
};

// See https://pusher.com/docs/channels/library_auth_reference/auth-signatures/ for the format of this object.
const onAuthorizer = (channelName: string, socketId: string) => {
const user = JSON.stringify({ user_id: 12345 });
const stringToSign = socketId + ':' + channelName + ':' + user;
const pusherKey = '<YOUR PUSHER KEY>';
const pusherSecret = '<YOUR PUSHER SECRET>';
const signature = CryptoES.HmacSHA256(stringToSign, pusherSecret);
return {
auth: pusherKey + ':' + signature,
channel_data: user,
shared_secret: 'foobar',
};
};

const trigger = async () => {
try {
await AsyncStorage.multiSet([
Expand Down
5 changes: 5 additions & 0 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,11 @@ cross-spawn@^6.0.0:
shebang-command "^1.2.0"
which "^1.2.9"

crypto-es@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/crypto-es/-/crypto-es-1.2.7.tgz#754a6d52319a94fb4eb1f119297f17196b360f88"
integrity sha512-UUqiVJ2gUuZFmbFsKmud3uuLcNP2+Opt+5ysmljycFCyhA0+T16XJmo1ev/t5kMChMqWh7IEvURNCqsg+SjZGQ==

dayjs@^1.8.15:
version "1.11.3"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.3.tgz#4754eb694a624057b9ad2224b67b15d552589258"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pusher/pusher-websocket-react-native",
"version": "1.0.1",
"version": "1.0.2",
"description": "Pusher Channels Client for React Native",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down

0 comments on commit b2f077b

Please sign in to comment.