mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-10 07:15:53 +00:00
feat: allow for unlimitedAllowList + typedefs snuck in by accident (#1813)
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test (20.x) (push) Has been cancelled
test / test (22.x) (push) Has been cancelled
test / api-test (22.x) (push) Has been cancelled
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test (20.x) (push) Has been cancelled
test / test (22.x) (push) Has been cancelled
test / api-test (22.x) (push) Has been cancelled
* feat: allow for unlimitedAllowList * feat: add clearer types to extensions
This commit is contained in:
Vendored
+40
-30
@@ -1,51 +1,61 @@
|
||||
import type { Actor } from '@heyputer/backend/src/services/auth/Actor.js';
|
||||
import type { MeteringService } from '@heyputer/backend/src/services/MeteringService/MeteringService.ts';
|
||||
import type { DBKVStore } from '@heyputer/backend/src/services/repositories/DBKVStore/DBKVStore.ts';
|
||||
import type { SUService } from '@heyputer/backend/src/services/SUService.js';
|
||||
import type { RequestHandler } from 'express';
|
||||
import type helpers from '../src/backend/src/helpers.js';
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
actor: any; // TODO
|
||||
namespace Express {
|
||||
interface Request {
|
||||
services: { get: <T extends (keyof ServiceNameMap ) | (string & {})>(string: T)=> T extends keyof ServiceNameMap ? ServiceNameMap[T] : unknown }
|
||||
actor: Actor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type EndpointOptions = {
|
||||
allowedMethods?: string[]
|
||||
subdomain?: string
|
||||
noauth?: boolean
|
||||
interface EndpointOptions {
|
||||
allowedMethods?: string[]
|
||||
subdomain?: string
|
||||
noauth?: boolean
|
||||
}
|
||||
|
||||
type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch';
|
||||
|
||||
type AddRouteFunction = (path: string, options: EndpointOptions, handler: RequestHandler) => void
|
||||
export type AddRouteFunction = (path: string, options: EndpointOptions, handler: RequestHandler) => void;
|
||||
|
||||
type RouterMethods = {
|
||||
[K in HttpMethod]: {
|
||||
(path: string, options: EndpointOptions, handler: RequestHandler): void;
|
||||
(path: string, handler: RequestHandler, options?: EndpointOptions): void;
|
||||
};
|
||||
[K in HttpMethod]: {
|
||||
(path: string, options: EndpointOptions, handler: RequestHandler): void;
|
||||
(path: string, handler: RequestHandler, options?: EndpointOptions): void;
|
||||
};
|
||||
};
|
||||
|
||||
interface CoreRuntimeModule {
|
||||
util: {
|
||||
helpers: typeof helpers,
|
||||
}
|
||||
}
|
||||
|
||||
type CoreRuntimeModule = {
|
||||
util: {
|
||||
helpers: typeof helpers,
|
||||
}
|
||||
}
|
||||
type StripPrefix<TPrefix extends string, T extends string> = T extends `${TPrefix}.${infer R}` ? R : never;
|
||||
// TODO DS: define this globally in core to use it there too
|
||||
interface ServiceNameMap {
|
||||
'meteringService': { meteringService: MeteringService } & MeteringService // TODO DS: squash into a single class without wrapper
|
||||
'puter-kv': DBKVStore
|
||||
'su': SUService
|
||||
|
||||
}
|
||||
interface Extension extends RouterMethods {
|
||||
// import(module: 'core'): {
|
||||
// UserActorType: typeof UserActorType;
|
||||
// };
|
||||
import(module: 'core'): CoreRuntimeModule;
|
||||
import(module: string): any;
|
||||
import<T extends (`service:${keyof ServiceNameMap}` | 'core') | (string & {})>(module: T): T extends `service:${infer R extends keyof ServiceNameMap}`
|
||||
? ServiceNameMap[R]
|
||||
: T extends 'core'
|
||||
? CoreRuntimeModule
|
||||
: unknown;
|
||||
}
|
||||
|
||||
declare global {
|
||||
// Declare the extension variable
|
||||
const extension: Extension;
|
||||
const config: Record<string | number | symbol, unknown>;
|
||||
const global_config: Record<string | number | symbol, unknown>;
|
||||
// Declare the extension variable
|
||||
const extension: Extension;
|
||||
const config: Record<string | number | symbol, unknown>;
|
||||
const global_config: Record<string | number | symbol, unknown>;
|
||||
}
|
||||
|
||||
export { };
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"unlimitedUsage": false,
|
||||
"unlimitedAllowList": [
|
||||
"admin"
|
||||
],
|
||||
"allowedGlobalUsageUsers": [
|
||||
"06ab2f87-aef5-441b-9c60-debbb8d24dda",
|
||||
"d8fd169b-4e93-484a-bd84-115b5a2f0ed4"
|
||||
|
||||
@@ -9,8 +9,7 @@ extension.on('metering:overrideDefaultSubscription', async (/** @type {{actor: i
|
||||
extension.on('metering:registerAvailablePolicies', async (
|
||||
/** @type {{actor: import('@heyputer/backend/src/services/auth/Actor').Actor, availablePolicies: unknown[]}} */event) => {
|
||||
// bit of a stub implementation for OSS, technically can be always free if you set this config true
|
||||
if ( config.unlimitedUsage ) {
|
||||
console.warn('WARNING!!! unlimitedUsage is enabled, this is not recommended for production use');
|
||||
if ( config.unlimitedUsage || config.unlimitedAllowList?.length ) {
|
||||
event.availablePolicies.push({
|
||||
id: 'unlimited',
|
||||
monthUsageAllowance: 5_000_000 * 1_000_000 * 100, // unless you're like, jeff's, mark's, and elon's illegitamate son, you probably won't hit $5m a month
|
||||
@@ -20,6 +19,13 @@ extension.on('metering:registerAvailablePolicies', async (
|
||||
});
|
||||
|
||||
extension.on('metering:getUserSubscription', async (/** @type {{actor: import('@heyputer/backend/src/services/auth/Actor').Actor, userSubscriptionId: string}} */event) => {
|
||||
event.userSubscriptionId = event?.actor?.type?.user?.subscription?.active ? event.actor.type.user.subscription?.tier : undefined;
|
||||
const userName = event?.actor?.type?.user?.username;
|
||||
if ( config.unlimitedAllowList?.includes(userName) ) {
|
||||
console.warn(`WARNING!!! User ${userName} is on unlimited usage allow list, this is not recommended for production use`);
|
||||
event.userSubscriptionId;
|
||||
}
|
||||
else {
|
||||
event.userSubscriptionId = event?.actor?.type?.user?.subscription?.active ? event.actor.type.user.subscription?.tier : undefined;
|
||||
}
|
||||
// default location for user sub, but can techinically be anywhere else or fetched on request
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/** @type {import('@heyputer/backend/src/services/MeteringService/MeteringServiceWrapper.mjs').MeteringServiceWrapper} */
|
||||
const meteringServiceWrapper = extension.import('service:meteringService');
|
||||
|
||||
// TODO DS: move this to its own router and just use under this path
|
||||
|
||||
@@ -17,6 +17,5 @@
|
||||
"**/tests/**",
|
||||
"node_modules",
|
||||
"dist",
|
||||
"extensions"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user