Skip to content

add custom authorizer example #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 21, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:+'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't better to define a specific version?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, the latest one is 2.4.0

api 'com.google.code.gson:gson:+'
}
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
Copy link
Contributor

@fbenevides fbenevides Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I think we can add this information to the README file. WDYT?

// ============
// 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