# OpenPass Roku SDK

[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
[![BrightScript](https://img.shields.io/badge/BrightScript-8A2BE2)](https://img.shields.io/badge/BrightScript-8A2BE2)
[![Roku Package Manager](https://img.shields.io/badge/Roku_Package_Manager-compatible-blue)](https://img.shields.io/badge/Roku_Package_Manager-compatible-blue)

The OpenPass Roku SDK makes it easier to integrate OpenPass directly on your Roku channels.

## Installation

### ropm

The preferred installation method is via [ropm](https://www.npmjs.com/package/ropm)

```bash
 ropm install @openpass/openpass-roku-sdk
```

### Manually

Copy `openpass_openpassrokusdk` files inside your source folder

## Requirements

In order to use this SDK you will need the following requirements

1. Install Node.JS from here
2. Install the [Roku Package Manager](https://github.com/rokucommunity/ropm) node module globally

   ```bash
   npm i ropm -g
   ```

3. Install [BrighterScript](https://github.com/rokucommunity/brighterscript) module globally

   ```bash
   npm install brighterscript -g
   ```

4. At project root level run

   ```bash
   ropm install
   ```

5. Enable Developer Mode on you Roku device, you can see more [here](https://blog.roku.com/developer/developer-setup-guide)

6. In order to use `npm scripts` to run the project locally, you will need to add the following ENV VARS to your system:

- `ROKU_HOST`: This is the IP Address of your Roku device.
- `ROKU_DEV_PASSWORD`: This is the password you set for your Roku device when `Developer Mode` was enabled.

To add the variables to your system for Mac or Linux:

- If using `zsh` as your shell

  ```bash
  echo 'export ROKU_DEV_PASSWORD=<YOUR_DEVICE_PASSWORD>' >> ~/.zshrc
  echo 'export ROKU_HOST=<YOUR_DEVICE_HOST_IP>' >> ~/.zshrc
  ```

- If using `bash` as your shell

  ```bash
  echo 'export ROKU_DEV_PASSWORD=<YOUR_DEVICE_PASSWORD>' >> ~/.bash_profile
  echo 'export ROKU_HOST=<YOUR_DEVICE_HOST_IP>' >> ~/.bash_profile
  ```

To add the variables to your system if using Windows

```bash
    setx ROKU_DEV_PASSWORD "<YOUR_DEVICE_PASSWORD>"
    setx ROKU_HOST "<ROKU_HOST>"
```

## Usage

1. Install the package via [ropm](https://www.npmjs.com/package/ropm)

```bash
 ropm install @openpass/openpass-roku-sdk
```

2. You will need to create 2 [tasks nodes](https://developer.roku.com/en-ca/docs/references/scenegraph/control-nodes/task.md) that will allow for specify a functions to be spawned in a different thread, you can do that like the following example:

create a task for Authorize Device flow: `tasks/AuthorizeDeviceTask.brs`

```brightscript
  sub Init()
    m.top.functionName = "AuthorizeDevice"
  end sub

  sub AuthorizeDevice()
    ' Your client Id
    clientId = "YOUR_CLIENT_ID"

    ' Init client
    m.op = openpass_openpassrokusdk_OpenPass()

    ' optionalParams = { polling_timeout: 200}
    ' optionalParams = { openpass_base_url: "www.differenturl.com", polling_timeout: 4000}
    ' optionalParams = { openpass_base_url: "www.differenturl.com"}
    optionalParams = { enable_logging: true }

    m.op.Init(clientId, AuthCallback, optionalParams)

    ' Start sign in process
    m.op.SignIn()

    ' m.op.SignOut()
  end sub

  sub AuthCallback(state, data)

    print state
    _states = {
      "SignedIn": 0,
      "SignedOut": 1,
      "Error": 2,
      "Loading": 3,
      "Polling": 4,
      "Refreshable": 5 ' Signed In but needs to refresh
    }

    if state = _states.SignedIn
      HandleSignedIn(data)
    else if state = _states.Polling
      HandlePolling(data)
    ' else if state = _states.Error
    '   HandleSignOut()
    end if

  end sub

  sub HandleSignedIn(data)
    authorizedDevice = CreateObject("roSGNode", "ContentNode")
    authorizedDevice.addFields(data["device_token_success"])
    m.top.authorizedDevice = authorizedDevice
  end sub

  sub HandlePolling(data)
    authDevice = CreateObject("roSGNode", "ContentNode")
    authDevice.addFields(data["authorize_device_success"])
    m.top.authDevice =authDevice
  end sub

```

and `tasks/AuthorizeDeviceTask.xml`

```xml
<?xml version="1.0" encoding="utf-8"?>

<component name="AuthorizeDeviceTask" extends="Task">
  <interface>
    <field id="authDevice" type="node" />
    <field id="authorizedDevice" type="node" />
    <field id="signedOut" type="node" />
  </interface>

  <!-- Import library -->
  <script type="text/brightscript"
    uri="pkg:/source/roku_modules/openpass_openpassrokusdk/dist/OpenPass.brs" />

  <script type="text/brightscript" uri="AuthorizeDeviceTask.brs" />
</component>
```

3. Implement your recently created tasks where you need:

```brightscript

sub DeviceAuthorization()
  m.authTask = CreateObject("roSGNode", "AuthorizeDeviceTask")
  m.authTask.ObserveField("authDevice", "OnAuthDeviceCompleted")
  m.authTask.ObserveField("authorizedDevice", "OnAuthenticateTaskCompleted")
  m.authTask.ObserveField("signedOut", "OnSignedOutComplete")

  m.authTask.control = "run"
end sub

' Get device token
sub OnAuthDeviceCompleted()
  print "authorize device"
  print m.authTask.authDevice
  m.SigningScreen.authDevice = m.authTask.authDevice
end sub

' Get Authorized information
sub OnAuthenticateTaskCompleted()
  print "authorized"
  print m.authTask.authorizedDevice
  m.SigningScreen.authorizedDevice = m.authTask.authorizedDevice
  ' Do what you need with the response
end sub

sub OnSignedOutComplete()
  print "signedOut"
end sub
```

## Development

The OpenPass SDK is a standalone headless library defined and managed by the Roku Package Manager. As such the `OpenPass SDK` is the primary way for developing the SDK. Use VSCode to open `openpass-roku-sdk` to begin development.

- Start your dev Server: `yarn start` or `bsc --watch --deploy --host <YOUR_DEVICE_HOST_IP> --password <YOUR_DEVICE_PASSWORD>`

- Lint the project: `yarn start` or `bsc --create-package false --copy-to-staging false`

## Tests

See [Tests README](https://github.com/openpass-sso/openpass-roku-sdk/blob/main/tests/README.md).

## Generate Docs

- `npm run docs`

## Project Documentation

- [Getting Started](documentation/01-getting-started.md)
- [Project Architecture](documentation/02-project-architecture.md)
- [Quick Usage](documentation/03-quick-usage.md)

## License

OpenPass is released under the MIT license. [See LICENSE](https://github.com/openpass-sso/openpass-roku-sdk/blob/master/LICENSE.md) for details.
