Skip to content
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

Adding Online with Auth and Custom Cloud BigPeer Endpoint #4

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

skylerjokiel
Copy link
Collaborator

@skylerjokiel skylerjokiel commented Oct 16, 2024

This PR adds the following two capabilities:

  1. Online with Authentication using a custom webhook
  2. Custom Cloud Big Peer Endpoint

Online with Authentication

Online with authentication hits a custom webhook called replit-auth using the manager01 token.

The token object is generic and defined in the webhook handler. Customer implementing real authentication should replace the token with a securely crafted application token.

Custom Cloud Big Peer Endpoint

To add the custom Big Peer endpoint there are two urls that needing updating.

Updating the identity endpoint. In this example below we are hitting the cloud-dev endpoint which is a Ditto internal dev endpoint. You can get this endpoint by working with your Ditto Customer Experience engineer.

final identity = await OnlineWithAuthenticationIdentity.create(
      appID: appID,
      authenticationHandler: authenticationHandler,
      customAuthUrl: "https://$appID.cloud-dev.ditto.live" // Custom Big Peer endpoint
      );

Updating the websocket endpoint. This endpoint represents the websocket endpoint that Ditto will be syncing data over. This is done by adding a websocket endpoint to a custom transport config.

    // Using a custom transport config to specify the websocket endpoint of a custom Big Peer Endpoint
    final peerToPeer = PeerToPeer.all();
    final connect = Connect(webSocketUrls: {"wss://$appID.cloud-dev.ditto.live"});
    final transportConfig = TransportConfig(peerToPeer: peerToPeer, connect: connect);
    ditto.setTransportConfig(transportConfig);

Custom webhook code

This code is being hosed on replit.

image

// Ditto Permissions Example Authentication Server

let express = require("express");
let cors = require("cors");
let body = require("body-parser");
let app = express();

app.use(cors());
app.use(body.json());

// List of user IDs.
//// Note: This is just an example. You should consider using Auth tools such as Auth0 to authenticate
const users = {
  customer: { id: "customer01" },
  manager: { id: "manager01" },
  employee: { id: "employee01" },
};

app.post("/auth", async (req, res) => {
  const token = req.body.token;
  console.log(`received new request :[${token}]`);

  const customerID = users.customer.id;
  const managerID = users.manager.id;
  const employeeID = users.employee.id;

  if (token !== customerID && token !== managerID && token !== employeeID) {
    res.statusCode = 401;
    return res.json({
      authenticate: false,
      userInfo: `Incorrect token ${token}`,
    });
  }

  let payload = {
    authenticate: true,
    expirationSeconds: 610000,
    userID: customerID,
  };

  if (token === customerID) {
    /** Customers can only see / edit their own docs **/
    payload.permissions = {
      read: {
        everything: false,
        queriesByCollection: {
          docs: [`_id.userID == \'${customerID}\'`],
        },
      },
      write: {
        everything: false,
        queriesByCollection: {
          docs: [`_id.userID == \'${customerID}\'`],
        },
      },
    };
    payload.role = "customer";
  } else if (token === managerID) {
    /** Managers can see / edit all docs **/
    payload.permissions = {
      read: {
        everything: true,
        queriesByCollection: {},
      },
      write: {
        everything: true,
        queriesByCollection: {},
      },
    };
    payload.role = "manager";
  } else if (token === employeeID) {
    /** Employee can see all docs but cannot edit any **/
    payload.permissions = {
      read: {
        everything: true,
        queriesByCollection: {},
      },
      write: {
        everything: false,
        queriesByCollection: {},
      },
    };
    payload.role = "employee";
  }

  try {
    res.json(payload);
    console.log(payload);
  } catch (err) {
    console.error(err);
    res.statusCode = 500;
    res.json({
      authenticate: false,
      userInfo: err.message,
    });
  }
});

app.get("/", async (req, res) => {
  console.log("Hello World!");
  res.send("Hello, World!");
});

const PORT = process.env.PORT || 80;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

module.exports = app;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant