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

feat: Add API key endpoints [DEV-3793] #510

Merged
merged 45 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
0b0b38b
Add base endpoints for Stripe integration
Feb 29, 2024
e50cece
Add swagger docs and make it as separate swagger for admin and api
Mar 1, 2024
77bb822
- Add Stripe webhook handling
Mar 9, 2024
a036a02
Add auth routes to admin
Mar 10, 2024
b44b322
Lint and format
Mar 10, 2024
d987e54
swagger changes
Mar 10, 2024
a4c28dc
Get rid of /admin/checkout and move it to /admin/subscriptions
Mar 18, 2024
39d8a42
Change endpoint in swagger
Mar 19, 2024
46baaa6
Fix swagger generation and add API routes
Mar 20, 2024
769b520
Fix swagger request body for subscription update
Mar 20, 2024
d39e55f
Fix stripeSync function
Mar 20, 2024
4fcd102
Get permissions from the M2M token
Mar 23, 2024
b985ec5
Sync updated and small clean-ups
Mar 24, 2024
64ea85b
Clean-ups
Mar 24, 2024
ab0da5b
Add trial period days to subscription creation
Mar 24, 2024
71f60d3
Get also trilaing subsriptions
Mar 25, 2024
042174b
Get rd of Stripe naming
Mar 25, 2024
b366935
Small cleeanups and refactoring
Mar 26, 2024
85d0aed
Merge remote-tracking branch 'origin/develop' into DEV-3671
Mar 27, 2024
9ef7459
Make swagger changes
Mar 27, 2024
dea3a23
Add encryption/decryption to API key
Apr 1, 2024
0413eb2
Change API logic a bit and introduce API key endpoints
Apr 1, 2024
91957b6
MAkes linter happy
Apr 1, 2024
7cf813f
Merge remote-tracking branch 'origin/develop' into DEV-3793
Apr 8, 2024
3df21b2
Merge remote-tracking branch 'origin/develop' into DEV-3793
Apr 8, 2024
13be89f
Get rid of apiKeyHash
Apr 9, 2024
e0fc23e
Lint
Apr 9, 2024
a2fb347
Push swagger file
Apr 9, 2024
7b232eb
Fix required field in swagger
Apr 9, 2024
2226a48
Fix swagger date-time
Apr 9, 2024
5a4fd53
Fix name field in APIKeyCreateRequestBody
Apr 9, 2024
a4cc615
Merge remote-tracking branch 'origin/develop' into DEV-3793
Apr 11, 2024
a0a953a
Get rid of env variables and make them constants
Apr 11, 2024
1804717
Move to bcrypt and HMAC API key generating
Apr 13, 2024
f5ce736
Merge branch 'develop' into DEV-3793
Apr 13, 2024
be42f84
Merge branch 'develop' into DEV-3793
Apr 16, 2024
e7385dd
Add an ability to add several endpoints into CORS
Apr 16, 2024
7c1775d
npm run format
ankurdotb Apr 17, 2024
4791c0c
npm run build:swagger
ankurdotb Apr 17, 2024
ef9744f
Update .prettierignore
ankurdotb Apr 17, 2024
5458219
Rename API_SECRET_KEY_LENGTH to API_KEY_LENGTH
ankurdotb Apr 17, 2024
b0bae74
Update text
ankurdotb Apr 17, 2024
5be29b5
npm update
ankurdotb Apr 17, 2024
95b8b07
Move to UTC time comparing
Apr 17, 2024
ec42e7e
npm run format
ankurdotb Apr 17, 2024
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
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ By default, `ENABLE_AUTHENTICATION` is set to off/`false`. To enable external Ve
2. `LOGTO_WEBHOOK_SECRET`: Webhook secret to authenticate incoming webhook requests from LogTo.
5. **Miscellaneous**
1. `COOKIE_SECRET`: Secret for cookie encryption.
2. `API_KEY_PREFIX` (optional): Prefix for API keys. (Default "caas")
ankurdotb marked this conversation as resolved.
Show resolved Hide resolved
3. `API_KEY_LENGTH` (optional): Length of API keys. (Default 32)
ankurdotb marked this conversation as resolved.
Show resolved Hide resolved
4. `API_KEY_EXPIRATION` (optional): Expiration time for API keys in month. (Default 1 month)
ankurdotb marked this conversation as resolved.
Show resolved Hide resolved

#### Faucet settings

Expand All @@ -107,6 +110,15 @@ some tokens on the testnet for making the process simpler.
2. `FAUCET_URI`: Faucet service API endpoint (Default: `https://faucet-api.cheqd.network/credit`)
3. `TESTNET_MINIMUM_BALANCE`: Minimum balance on account before it is automatically topped up from the faucet. This value should be expressed as an integer in `CHEQ` tokens, which will then be converted in the background to `ncheq` denomination. Account balance check is carried out on every account creation/login. (Default: 10,000 CHEQ testnet tokens)

#### Stripe integration

The application supports Stripe integration for payment processing.

1. `STRIPE_ENABLED` - Enable/disable Stripe integration (`false` by default)
2. `STRIPE_SECRET_KEY` - Secret key for Stripe API. Please, keep it secret on deploying
3. `STRIPE_PUBLISHABLE_KEY` - Publishable key for Stripe API.
4. `STRIPE_WEBHOOK_SECRET` - Secret for Stripe Webhook.

### 3rd Party Connectors

The app supports 3rd party connectors for credential storage and delivery.
Expand Down
22 changes: 22 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ ARG LOGTO_WEBHOOK_SECRET
ARG ENABLE_DATADOG=false
ARG LOG_LEVEL=info

# API generation
ARG API_KEY_PREFIX="caas"
ARG API_KEY_LENGTH=32
ARG API_KEY_EXPIRATION=1

# Verida connector: build-time
ARG ENABLE_VERIDA_CONNECTOR=false
ARG VERIDA_NETWORK=testnet
Expand All @@ -81,6 +86,12 @@ ARG ENABLE_ACCOUNT_TOPUP=false
ARG FAUCET_URI=https://faucet-api.cheqd.network/credit
ARG TESTNET_MINIMUM_BALANCE=1000

# Stripe
ARG STRIPE_ENABLED=false
ARG STRIPE_SECRET_KEY
ARG STRIPE_PUBLISHABLE_KEY
ARG STRIPE_WEBHOOK_SECRET

# Environment variables: base configuration
ENV NPM_CONFIG_LOGLEVEL ${NPM_CONFIG_LOGLEVEL}
ENV PORT ${PORT}
Expand Down Expand Up @@ -113,6 +124,11 @@ ENV LOGTO_WEBHOOK_SECRET ${LOGTO_WEBHOOK_SECRET}
ENV ENABLE_DATADOG ${ENABLE_DATADOG}
ENV LOG_LEVEL ${LOG_LEVEL}

# API generatioin
ENV API_KEY_PREFIX ${API_KEY_PREFIX}
ENV API_KEY_LENGTH ${API_KEY_LENGTH}
ENV API_KEY_EXPIRATION ${API_KEY_EXPIRATION}

# Faucet setup
ENV ENABLE_ACCOUNT_TOPUP ${ENABLE_ACCOUNT_TOPUP}
ENV FAUCET_URI ${FAUCET_URI}
Expand All @@ -125,6 +141,12 @@ ENV POLYGON_RPC_URL ${POLYGON_RPC_URL}
ENV VERIDA_PRIVATE_KEY ${VERIDA_PRIVATE_KEY}
ENV POLYGON_PRIVATE_KEY ${POLYGON_PRIVATE_KEY}

# Environment variables: Stripe
ENV STRIPE_SECRET_KEY ${STRIPE_SECRET_KEY}
ENV STRIPE_PUBLISHABLE_KEY ${STRIPE_PUBLISHABLE_KEY}
ENV STRIPE_WEBHOOK_SECRET ${STRIPE_WEBHOOK_SECRET}
ENV STRIPE_ENABLED ${STRIPE_ENABLED}

# Set ownership permissions
RUN chown -R node:node /home/node/app

Expand Down
49 changes: 44 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"scripts": {
"build": "npm run build:swagger && npm run build:app",
"build:app": "tsc",
"build:swagger": "swagger-jsdoc --definition src/static/swagger-options.json -o src/static/swagger.json ./src/controllers/*.ts ./src/types/swagger-types.ts",
"build:swagger-api": "swagger-jsdoc --definition src/static/swagger-api-options.json -o src/static/swagger-api.json ./src/controllers/api/*.ts ./src/types/swagger-api-types.ts",
"build:swagger-admin": "swagger-jsdoc --definition src/static/swagger-admin-options.json -o src/static/swagger-admin.json ./src/controllers/admin/*.ts ./src/types/swagger-admin-types.ts",
"build:swagger": "npm run build:swagger-api && npm run build:swagger-admin",
"start": "node dist/index.js",
"start:local": "npm run build:app && npm run start",
"format": "prettier --write '**/*.{js,ts,cjs,mjs,json}'",
Expand Down Expand Up @@ -84,6 +86,7 @@
"express-validator": "^7.0.1",
"helmet": "^7.1.0",
"http-status-codes": "^2.3.0",
"js-sha3": "^0.9.3",
"json-stringify-safe": "^5.0.1",
"jsonwebtoken": "^9.0.2",
"jwt-decode": "^4.0.0",
Expand All @@ -94,8 +97,9 @@
"pg-connection-string": "^2.6.2",
"secp256k1": "^5.0.0",
"sqlite3": "^5.1.7",
"swagger-ui-express": "^5.0.0",
"stripe": "^14.18.0",
"swagger-ui-dist": "5.10.5",
"swagger-ui-express": "^5.0.0",
"typeorm": "^0.3.20",
"uint8arrays": "^5.0.2",
"uri-js": "^4.4.1"
Expand Down
96 changes: 85 additions & 11 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import path from 'path';
import swaggerUi from 'swagger-ui-express';
import { StatusCodes } from 'http-status-codes';

import { CredentialController } from './controllers/credential.js';
import { AccountController } from './controllers/account.js';
import { CredentialController } from './controllers/api/credential.js';
import { AccountController } from './controllers/api/account.js';
import { Authentication } from './middleware/authentication.js';
import { Connection } from './database/connection/connection.js';
import { CredentialStatusController } from './controllers/credential-status.js';
import { CredentialStatusController } from './controllers/api/credential-status.js';
import { CORS_ALLOWED_ORIGINS, CORS_ERROR_MSG } from './types/constants.js';
import { LogToWebHook } from './middleware/hook.js';
import { Middleware } from './middleware/middleware.js';
Expand All @@ -20,12 +20,18 @@ import * as dotenv from 'dotenv';
dotenv.config();

// Define Swagger file
import swaggerDocument from './static/swagger.json' assert { type: 'json' };
import { PresentationController } from './controllers/presentation.js';
import { KeyController } from './controllers/key.js';
import { DIDController } from './controllers/did.js';
import { ResourceController } from './controllers/resource.js';
import { FailedResponseTracker } from './middleware/event-tracker.js';
import swaggerAPIDocument from './static/swagger-api.json' assert { type: 'json' };
import swaggerAdminDocument from './static/swagger-admin.json' assert { type: 'json' };
import { PresentationController } from './controllers/api/presentation.js';
import { KeyController } from './controllers/api/key.js';
import { DIDController } from './controllers/api/did.js';
import { ResourceController } from './controllers/api/resource.js';
import { ResponseTracker } from './middleware/event-tracker.js';
import { ProductController } from './controllers/admin/product.js';
import { SubscriptionController } from './controllers/admin/subscriptions.js';
import { PriceController } from './controllers/admin/prices.js';
import { WebhookController } from './controllers/admin/webhook.js';
import { APIKeyController } from './controllers/admin/api-key.js';

let swaggerOptions = {};
if (process.env.ENABLE_AUTHENTICATION === 'true') {
Expand Down Expand Up @@ -71,7 +77,7 @@ class App {
this.express.use(cookieParser());
const auth = new Authentication();
// EventTracking
this.express.use(new FailedResponseTracker().trackJson);
this.express.use(new ResponseTracker().trackJson);
// Authentication
if (process.env.ENABLE_AUTHENTICATION === 'true') {
this.express.use(
Expand All @@ -96,7 +102,19 @@ class App {
}
this.express.use(express.text());

this.express.use('/swagger', swaggerUi.serve, swaggerUi.setup(swaggerDocument, swaggerOptions));
this.express.use(
'/swagger',
swaggerUi.serveFiles(swaggerAPIDocument, swaggerOptions),
swaggerUi.setup(swaggerAPIDocument, swaggerOptions)
);
if (process.env.STRIPE_ENABLED === 'true') {
this.express.use(
'/admin/swagger',
swaggerUi.serveFiles(swaggerAdminDocument),
swaggerUi.setup(swaggerAdminDocument)
);
this.express.use(Middleware.setStripeClient);
}
this.express.use(auth.handleError);
this.express.use(async (req, res, next) => await auth.accessControl(req, res, next));
}
Expand Down Expand Up @@ -206,6 +224,62 @@ class App {
express.static(path.join(process.cwd(), '/dist'), { extensions: ['js'], index: false })
);

// Portal
// Product
if (process.env.STRIPE_ENABLED === 'true') {
app.get(
'/admin/product/list',
ProductController.productListValidator,
new ProductController().listProducts
);
app.get(
'/admin/product/get/:productId',
ProductController.productGetValidator,
new ProductController().getProduct
);

// Prices
app.get('/admin/price/list', PriceController.priceListValidator, new PriceController().getListPrices);

// Subscription
app.post(
'/admin/subscription/create',
SubscriptionController.subscriptionCreateValidator,
new SubscriptionController().create
);
app.post(
'/admin/subscription/update',
SubscriptionController.subscriptionUpdateValidator,
new SubscriptionController().update
);
app.get('/admin/subscription/get', new SubscriptionController().get);
app.get(
'/admin/subscription/list',
SubscriptionController.subscriptionListValidator,
new SubscriptionController().list
);
app.delete(
'/admin/subscription/cancel',
SubscriptionController.subscriptionCancelValidator,
new SubscriptionController().cancel
);
app.post(
'/admin/subscription/resume',
SubscriptionController.subscriptionResumeValidator,
new SubscriptionController().resume
);

// API key
app.post('/admin/api-key/create', APIKeyController.apiKeyCreateValidator, new APIKeyController().create);
app.post('/admin/api-key/update', APIKeyController.apiKeyUpdateValidator, new APIKeyController().update);
app.get('/admin/api-key/get', APIKeyController.apiKeyGetValidator, new APIKeyController().get);
app.get('/admin/api-key/list', APIKeyController.apiKeyListValidator, new APIKeyController().list);
app.delete('/admin/api-key/revoke', APIKeyController.apiKeyRevokeValidator, new APIKeyController().revoke);

// Webhook
app.post('/admin/webhook', new WebhookController().handleWebhook);
}

// 404 for all other requests
app.all('*', (_req, res) => res.status(StatusCodes.BAD_REQUEST).send('Bad request'));
}
Expand Down
Loading
Loading