-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(project): access bridge initial structure * feat(project): yarn * feat(project): add lint-staged * feat(project): error for unused imports * feat(project): remove not needed ls-lint * feat(project): add access tests * feat(project): rename error message * feat(project): readme and docs * chore: rename project in package * feat(project): include SIMS authorization * chore: replace jw/fet with standard prettier config * chore: access-bridge changes to not trigger e2e tests * chore: revert web env * feat(project): add stripe products endpoint * chore: yarn update * feat(project): move types in common package * feat(project): update allowed methods * chore: rename stripe service fnc name * feat(project): make authorization optional * feat(project): redefine functions with obj params * chore: consistent naming convention * feat(project): add test fixtures * feat(project): add tests for stripe * feat(project): fine-tune error descriptions * feat(project): add stripe checkout * chore: move types in common * chore: move types in common * feat(project): add tests for stripe checkout * feat(project): add more tests for checkout * chore: stripe checkout params * feat(project): add test mocks class * feat(project): add metadata in stripe checkout * feat(project): add viewer from auth token, handle plan external providers * feat(project): add viewer from auth token, handle plan external providers * chore: update readme * feat(project): update docs * feat(project): add account service * chore: remove unused util fnc * feat(project): add sentry * feat(project): replace node with vite * feat(project): refactor server to use express, refactor error handling as well as tests * feat(project): add types for express * chore: add .test in the test naimings * fix: vite version mismatch * feat(project): update docs * chore: add dummy env variables in the test-unit-snapshot workflow * feat(project): refactor services, decouple plans method * feat(project): add sentry source mapping * feat(project): add sentry version and environment * chore: remove debug sentry * feat(project): additional test build for not source mapping on test * feat(project): add stripe billing portal endpoint * chore: update readme * chore: add stripe dummy secret on test-unit workflow * chore: update checkout params * feat(project): add cors middleware * feat(project): add cors middleware * feat(project): add site_id in the route * feat(project): update port it can match google cloud run reqs * feat(project): use newer version of node to make happy sentry * feat(project): move error handling to the middleware * feat(project): add refresh passport * feat(project): simplify jw error usage * feat(project): refactor routes and middlewares * feat(project): refactor structure and namings * feat(project): add missing case for refresh passport test * feat(project): load envs at runtime * fix(search): override search query cache (#594) Co-authored-by: Mike van Veenhuijzen <mike@videodock.com> * feat(project): app metadata insertion * chore(project): add apple smart banner tag via env var * chore(project): add android native banner data via env var * refactor(project): make code more readable * refactor(project): add itunes related application metadata * refactor(project): function rename * feat(project): add injectable wrapper to common components (#598) * refactor(project): update services members visibility and explicit inject (#590) * feat(project): remove free and productIds from content-types.json (#605) * fix(e2e): fix tests after cleeng api update (#606) * chore(release): v6.6.0 * feat(project): refactor routes and middlewares * feat(project): rebase and stuff * feat(project): add generic payment service that other services will implement * feat(project): update products to use our own types * chore: add site_id in .env.example * feat(project): add stripe error handler in middleware * chore: update readme * chore: update comments on stripe payment service * chore: remove unused type * feat(project): update sentry and logger * chore: node-version * chore: revert node version * chore: update comment on checkout controller * chore: revert node version * chore: revert env to default * feat(project): modify types for products and prices * feat(project): add deployment file and docs * chore: update readme paths * feat(project): remove mode from checkout params * feat(project): remove stripe type * chore: remove vite build file --------- Co-authored-by: langemike <mikevv@gmail.com> Co-authored-by: Mike van Veenhuijzen <mike@videodock.com> Co-authored-by: Roy Schut <roy@videodock.com> Co-authored-by: Christiaan Scheermeijer <christiaan@videodock.com> Co-authored-by: Carina Dragan <92930790+CarinaDraganJW@users.noreply.github.com> Co-authored-by: Anton Lantukh <alantukh@jwplayer.com> Co-authored-by: Conventional Changelog Action <conventional.changelog.action@github.com>
- Loading branch information
1 parent
c27a1e6
commit aae2551
Showing
53 changed files
with
4,402 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export type JWError = { | ||
code: string; | ||
description: string; | ||
}; | ||
|
||
export type JWErrorResponse = { | ||
errors: JWError[]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export type PassportResponse = { | ||
passport: string; | ||
refresh_token: string; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
type Recurrence = { | ||
// The frequency at which a subscription is billed. One of `day`, `week`, `month`, or `year`. | ||
interval: 'day' | 'week' | 'month' | 'year'; | ||
// Recurrence duration, for example, `interval=month` and `duration=3` bills every 3 months. | ||
duration: number; | ||
// Trial period interval. For example, a month-long trial is different from a 30-day trial. | ||
trial_period_interval: 'day' | 'week' | 'month' | 'year'; | ||
// Duration of the trial period (in the unit defined by trial_period_interval). | ||
trial_period_duration: number | null; | ||
}; | ||
|
||
export type Price = { | ||
// Unique identifier for the object. | ||
store_price_id: string; | ||
// Dictionary of currencies, where the key is the currency code and the value is an object with an amount property. | ||
// Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase. | ||
currencies: { | ||
[currency_code: string]: { | ||
// The unit amount in cents (or local equivalent) to be charged, represented as a whole integer. | ||
amount: number | null; | ||
}; | ||
}; | ||
// Default currency code for this price. | ||
default_currency: string; | ||
// Recurrence details. Can be a Recurrence object or 'one_time'. | ||
recurrence: Recurrence | 'one_time'; | ||
// Billing scheme. For now, we only support `per_unit`. | ||
billing_scheme: 'per_unit'; | ||
}; | ||
|
||
export type Product = { | ||
// Unique identifier for the object. | ||
store_product_id: string; | ||
// The product's name, meant to be displayable to the customer. | ||
name: string; | ||
// The product's description, meant to be displayable to the customer. | ||
description: string; | ||
// The ID of the default price this product is associated with. | ||
default_store_price_id: string; | ||
// Array of price objects. | ||
prices: Price[]; | ||
}; | ||
|
||
// General checkout parameters type. Can be extended by specific payment providers, e.g. Stripe | ||
export type CheckoutParams = { | ||
price_id: string; | ||
success_url: string; | ||
cancel_url: string; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
type AccessOptions = { | ||
drm_policy_id: string; | ||
}; | ||
|
||
type PlanExternalProviders = { | ||
stripe?: string; | ||
apple?: string; | ||
google?: string; | ||
}; | ||
|
||
export type AccessControlPlan = { | ||
id: string; | ||
exp: number; | ||
}; | ||
|
||
export type Plan = { | ||
id: string; | ||
exp: number; | ||
access_model: 'free' | 'freeauth' | 'svod'; | ||
access: AccessOptions; | ||
metadata: { | ||
external_providers: PlanExternalProviders; | ||
}; | ||
}; | ||
|
||
export type PlansResponse = { | ||
total: number; | ||
page: number; | ||
page_length: number; | ||
plans: Plan[]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Application version - Used for tracking and identifying specific releases. | ||
# Automatically set to the version specified in package.json. | ||
# Helps in associating logs, errors, and other metrics with particular versions of the application. | ||
APP_VERSION=$npm_package_version | ||
|
||
# Secrets responsible for signing a request to authenticate with the JW Delivery Gateway. | ||
# In order to use the AC System this authentication is crucial. | ||
# The secrets can be found in the JW Dashboard, under the API Credentials in the top right settings icon. | ||
# Make sure the secrets are V1 and that they refer to the desired property. | ||
# For production env, use this reference on how to store them: https://cloud.google.com/run/docs/configuring/services/secrets | ||
APP_API_SECRET=customer_v1_secret | ||
# site_id or property_id represents the key that corresponds to the APP_API_SECRET defined earlier. | ||
APP_SITE_ID=customer_site_id | ||
# Stripe secret responsible for authenticating Stripe API calls | ||
APP_STRIPE_SECRET=stripe_secret | ||
|
||
# Non-secret variables | ||
# Specifies the network address or IP address on which the server listens for incoming connections. | ||
APP_BIND_ADDR=localhost | ||
# Specifies the port number on which the server listens for incoming connections. | ||
APP_BIND_PORT=8080 | ||
# Specifies the client URL responsible for access related stuff | ||
APP_ACCESS_CONTROL_API_HOST=https://cdn-dev.jwplayer.com | ||
# Specifies the client URL responsible for plans related stuff | ||
APP_SIMS_API_HOST=https://daily-sims.jwplayer.com | ||
|
||
# These are optional and should be added only if tracing with Sentry is needed | ||
# Set the APP_SENTRY_DSN variable to enable Sentry error tracking and performance monitoring. | ||
# Set APP_SENTRY_AUTH_TOKEN to allow Sentry to provide readable stack traces (source maps). | ||
# If this variable is not set, Sentry will not be initialized. | ||
# For production environments, ensure you configure the `APP_SENTRY_TRACE_RATE` | ||
# according to your monitoring needs to balance performance and resource usage. | ||
APP_SENTRY_DSN= | ||
APP_SENTRY_AUTH_TOKEN= | ||
APP_SENTRY_TRACE_RATE= | ||
APP_SENTRY_ORG_NAME= | ||
APP_SENTRY_PROJ_NAME= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module.exports = { | ||
extends: ['jwp/typescript'], | ||
rules: { | ||
"max-len": ["error", { "code": 120 }], | ||
"import/no-unused-modules": ["error"] | ||
}, | ||
env: { | ||
node: true, // Enables recognition of Node.js global variables and scoping rules | ||
}, | ||
ignorePatterns: ['build'], | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
node_modules | ||
build | ||
*.local | ||
.env | ||
# Sentry Config File | ||
.env.sentry-build-plugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
PACKAGE_JSON := ./package.json | ||
BACKUP_PACKAGE_JSON := ./package-backup.json | ||
ROOT_YARN_LOCK := ../../yarn.lock | ||
PROJECT_YARN_LOCK := ./yarn.lock | ||
|
||
# Default target: deploy and ensure cleanup runs regardless | ||
.PHONY: deploy | ||
deploy: check-setup backup-package modify-package copy-yarn-lock try-deploy post-deploy | ||
|
||
# Step 0: Check setup | ||
.PHONY: check-setup | ||
check-setup: | ||
@echo "Checking setup..." | ||
@command -v gcloud >/dev/null 2>&1 || { echo "Error: gcloud is not installed. Please install Google Cloud SDK."; exit 1; } | ||
@command -v yarn >/dev/null 2>&1 || { echo "Error: yarn is not installed. Please install Yarn."; exit 1; } | ||
@echo "All required tools are installed." | ||
@# Check if Google Cloud is configured | ||
@gcloud config get-value project >/dev/null 2>&1 || { echo "Error: Google Cloud project is not configured. Run 'gcloud init'."; exit 1; } | ||
@echo "Google Cloud is configured." | ||
|
||
# Step 1: Backup the original package.json | ||
.PHONY: backup-package | ||
backup-package: | ||
@echo "Deployment started..." | ||
@cp $(PACKAGE_JSON) $(BACKUP_PACKAGE_JSON) | ||
|
||
# Step 2: Modify `package.json` by removing internal dependencies | ||
# In a monorepo setup, internal packages are not deployed. This step ensures that only the relevant, | ||
# external dependencies are included in the `package.json` for deployment. | ||
.PHONY: modify-package | ||
modify-package: | ||
@# Use `sed` to remove specific internal dependencies by editing package.json in place | ||
@sed -i.bak '/"@jwp\/ott-common"/d' $(PACKAGE_JSON) | ||
@sed -i.bak '/"eslint-config-jwp"/d' $(PACKAGE_JSON) | ||
@rm -f $(PACKAGE_JSON).bak | ||
|
||
# Step 3: Copy the root `yarn.lock` to the project directory | ||
# To maintain dependency consistency in a monorepo, copy the root `yarn.lock` file to the project | ||
# directory so Google Cloud Run can correctly compare and resolve dependencies. | ||
.PHONY: copy-yarn-lock | ||
copy-yarn-lock: | ||
@cp $(ROOT_YARN_LOCK) $(PROJECT_YARN_LOCK) | ||
|
||
# Step 4: Deploy to Google Cloud Run | ||
.PHONY: try-deploy | ||
try-deploy: | ||
@{ \ | ||
set -e; \ | ||
trap 'make post-deploy; exit 1;' INT TERM HUP; \ | ||
gcloud run deploy access-bridge \ | ||
--source=. \ | ||
--platform=managed \ | ||
--region= \ | ||
--allow-unauthenticated; \ | ||
make post-deploy; \ | ||
} | ||
|
||
# Step 5: Cleanup (run whether deploy succeeds or fails) | ||
.PHONY: post-deploy | ||
post-deploy: restore-package clean | ||
|
||
# Step 6: Restore the original package.json | ||
.PHONY: restore-package | ||
restore-package: | ||
@mv $(BACKUP_PACKAGE_JSON) $(PACKAGE_JSON) | ||
|
||
# Step 7: Clean up copied yarn.lock | ||
.PHONY: clean | ||
clean: | ||
@rm -f $(PROJECT_YARN_LOCK) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
# Access Bridge | ||
|
||
A service that facilitates seamless communication between the Subscriber Identity Management System (SIMS) and Access Control services. It provides endpoints to generate access passports for authenticated viewers, ensuring secure and efficient access management. | ||
|
||
## Local Setup for Environment Variables | ||
|
||
To set up the project locally, you need to configure environment variables that are crucial for authenticating with the JW Delivery Gateway and for specifying server configurations. | ||
|
||
Here’s how you can set them up: | ||
|
||
Create a `.env.local` file in the root of this project and add the following variables: | ||
|
||
- APP_API_SITE_ID=customer_site_id | ||
- APP_API_SECRET=customer_v1_secret | ||
- APP_BIND_ADDR=localhost | ||
- APP_BIND_PORT=8080 | ||
- APP_ACCESS_CONTROL_API_HOST=https://cdn-dev.jwplayer.com | ||
<em>(Use https://cdn.jwplayer.com for production)</em> | ||
- APP_SIMS_API_HOST=https://daily-sims.jwplayer.com | ||
<em>(Use https://sims.jwplayer.com for production)</em> | ||
|
||
Make sure to replace the placeholder values (e.g., customer_v1_secret) with the actual values from your JW Dashboard. | ||
You can also copy and paste the contents of `.env.example` into `.env.local` and just adjust the APP_API_SECRET. | ||
|
||
## Getting started | ||
|
||
- Run `yarn` to install dependencies | ||
- Navigate to the platform directory `cd platforms/access-bridge` | ||
- Run tests through `yarn test` | ||
- Run `yarn start` to start the server | ||
|
||
## Exposed endpoints | ||
|
||
#### URL: `/v2/sites/{site_id}/access/generate` | ||
|
||
- **Method:** PUT | ||
- **Authorization:** Valid SIMS token | ||
- **Summary:** Generates a new passport for an authenticated viewer based on the information inside the SIMS token. | ||
- **Response:** | ||
```json | ||
{ | ||
"passport": "encrypted_passport", | ||
"refresh_token": "random_string" | ||
} | ||
``` | ||
|
||
#### URL: `/v2/sites/{site_id}/access/refresh` | ||
|
||
- **Method:** PUT | ||
- **Authorization:** Valid SIMS token | ||
- **Summary:** Regenerates an existing passport with a new expiry and a new refresh token. | ||
- **Request:** | ||
```json | ||
{ | ||
"refresh_token": "string" | ||
} | ||
``` | ||
- **Response:** | ||
```json | ||
{ | ||
"passport": "encrypted_passport", | ||
"refresh_token": "random_string" | ||
} | ||
``` | ||
|
||
#### URL: `/v2/sites/{site_id}/products` | ||
|
||
- **Method:** GET | ||
- **Authorization:** None | ||
- **Summary:** Lists all the corresponding stripe products with prices that are connected to the SIMS plans. | ||
- **Response:** [Product payment type](../../../ott-web-app/packages/common/types/payment.ts) | ||
```json | ||
[ | ||
{ | ||
// ... | ||
"id": "prod_QRUHbH7wK5HHPr", | ||
"default_price": "price_1PabInA9TD3ZjIM6EEnKSR7U", | ||
// ... | ||
"prices": [ | ||
{ | ||
// ... | ||
"id": "price_1PabInA9TD3ZjIM6EEnKSR7U", | ||
"currency": "usd", | ||
"unit_amount": 15000 | ||
// ... | ||
} | ||
] | ||
} | ||
// ... | ||
] | ||
``` | ||
|
||
#### URL: `/v2/sites/{site_id}/checkout` | ||
|
||
- **Method:** POST | ||
- **Authorization:** Valid SIMS token | ||
- **Summary:** Creates Payment Checkout Session URL where the viewer will be redirected to complete the payment. | ||
- **Request:** | ||
```json | ||
{ | ||
"price_id": "string", // id of the price that is about to be paid | ||
"mode": "string", // subscription (recurring) | payment (one time purchases) | ||
"success_url": "string", // redirect after successful payment | ||
"cancel_url": "string" // redirect after cancel / invalid payment | ||
} | ||
``` | ||
- **Response:** | ||
```json | ||
{ | ||
"url": "string" // url where the viewer will be redirected to complete the payment. | ||
} | ||
``` | ||
|
||
#### URL: `/v2/sites/{site_id}/billing-portal` | ||
|
||
- **Method:** POST | ||
- **Authorization:** Valid SIMS token | ||
- **Summary:** Generates Billing Portal Url, where the viewer can view / update their purchase info. | ||
- **Response:** | ||
```json | ||
{ | ||
"url": "billing-portal-url" | ||
} | ||
``` | ||
|
||
## Developer guidelines | ||
|
||
- Read the workspace guidelines here [developer-guidelines.md](./docs/developer-guidelines.md). | ||
- Read the deployment guidelines here [deployment.md](./docs/deployment.md). | ||
- Read the web platform guidelines here [developer-guidelines.md](../../docs/developer-guidelines.md). | ||
|
||
``` | ||
``` |
Oops, something went wrong.