UNPKG

wttp-core

Version:

Core contracts, interfaces, and TypeScript types for the Web3 Transfer Protocol (WTTP).

430 lines 15.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_HEADER = exports.DEFAULT_HEADERS = exports.STRICT_READ_ONLY_HEADER = exports.IMMUTABLE_PUBLIC_HEADER = exports.INTRA_SITE_HEADER = exports.API_HEADER = exports.READ_ONLY_PUBLIC_HEADER = exports.ADMIN_ONLY_HEADER = exports.PUBLIC_HEADER = exports.ORIGINS_PRESETS = exports.ORIGINS_IMMUTABLE_CONTENT = exports.ORIGINS_API_PATTERN = exports.ORIGINS_READ_ONLY_PUBLIC = exports.ORIGINS_READ_PUBLIC_WRITE_INTRA = exports.ORIGINS_READ_PUBLIC_WRITE_ADMIN = exports.ORIGINS_INTRA_SITE = exports.ORIGINS_BLACKLISTED = exports.ORIGINS_ADMIN_ONLY = exports.ORIGINS_PUBLIC = exports.MASTER_CHAIN_ID = exports.DEFAULT_ROLES = exports.INTRA_SITE_ROLE = exports.PUBLIC_ROLE = exports.BLACKLIST_ROLE = exports.DEFAULT_ADMIN_ROLE = exports.WRITE_METHODS_BITMASK = exports.READ_ONLY_METHODS_BITMASK = exports.ALL_METHODS_BITMASK = exports.Method = void 0; exports.getMethodCount = getMethodCount; exports.methodsToBitmask = methodsToBitmask; exports.bitmaskToMethods = bitmaskToMethods; exports.createOriginsArray = createOriginsArray; exports.createMixedOriginsArray = createMixedOriginsArray; exports.createCustomHeader = createCustomHeader; const ethers_1 = require("ethers"); // import type { HeaderInfoStruct } from '../typechain-types/contracts/BaseWTTPStorage'; // ============ Method Enum ============ /** * WTTP Methods Enum - mirrors the Solidity enum * Used for method-based access control and request handling */ var Method; (function (Method) { /** Retrieve only resource headers and metadata */ Method[Method["HEAD"] = 0] = "HEAD"; /** Retrieve resource content */ Method[Method["GET"] = 1] = "GET"; /** Submit data to be processed (not fully implemented in WTTP) */ Method[Method["POST"] = 2] = "POST"; /** Create or replace a resource */ Method[Method["PUT"] = 3] = "PUT"; /** Update parts of a resource */ Method[Method["PATCH"] = 4] = "PATCH"; /** Remove a resource */ Method[Method["DELETE"] = 5] = "DELETE"; /** Query which methods are supported for a resource */ Method[Method["OPTIONS"] = 6] = "OPTIONS"; /** Retrieve storage locations for resource data points */ Method[Method["LOCATE"] = 7] = "LOCATE"; /** Update resource headers */ Method[Method["DEFINE"] = 8] = "DEFINE"; })(Method || (exports.Method = Method = {})); // ============ Method Utilities ============ /** * Gets the total number of methods in the Method enum * @returns The count of methods (currently 9) */ function getMethodCount() { return Object.keys(Method).filter(key => !isNaN(Number(key))).length; } /** * Converts an array of methods to a bitmask representation * Used for efficient method permission storage (1 bit per method) * @param methods Array of WTTP methods to convert * @returns Bitmask representing allowed methods as uint16 */ function methodsToBitmask(methods) { let mask = 0; for (const method of methods) { mask |= (1 << method); } return mask; } /** * Converts a bitmask back to an array of methods * @param mask The bitmask to convert * @returns Array of methods represented by the bitmask */ function bitmaskToMethods(mask) { const methods = []; for (let i = 0; i < getMethodCount(); i++) { if (mask & (1 << i)) { methods.push(i); } } return methods; } /** * All methods bitmask - enables all 9 methods */ exports.ALL_METHODS_BITMASK = methodsToBitmask([ Method.HEAD, Method.GET, Method.POST, Method.PUT, Method.PATCH, Method.DELETE, Method.OPTIONS, Method.LOCATE, Method.DEFINE ]); /** * Read-only methods bitmask - only HEAD, GET, OPTIONS, LOCATE */ exports.READ_ONLY_METHODS_BITMASK = methodsToBitmask([ Method.HEAD, Method.GET, Method.OPTIONS, Method.LOCATE ]); /** * Write methods bitmask - POST, PUT, PATCH, DELETE, DEFINE */ exports.WRITE_METHODS_BITMASK = methodsToBitmask([ Method.POST, Method.PUT, Method.PATCH, Method.DELETE, Method.DEFINE ]); // ============ Default Roles ============ /** * Default admin role - uses ethers ZeroHash * Admins have full access to all resources and methods */ exports.DEFAULT_ADMIN_ROLE = ethers_1.ethers.ZeroHash; /** * Blacklist role - computed using keccak256("BLACKLIST_ROLE") * Accounts with this role are denied access to all methods */ exports.BLACKLIST_ROLE = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes("BLACKLIST_ROLE")); /** * Public access role - allows unrestricted access * Uses all 1s in bytes32 format for maximum permissiveness */ exports.PUBLIC_ROLE = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; /** * Intra-site communication role - for internal service-to-service communication * Different from existing roles, used for trusted internal operations */ exports.INTRA_SITE_ROLE = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes("INTRA_SITE_COMMUNICATION")); // ============ Role Collections ============ /** * Collection of all default roles for easy access */ exports.DEFAULT_ROLES = { ADMIN: exports.DEFAULT_ADMIN_ROLE, BLACKLIST: exports.BLACKLIST_ROLE, PUBLIC: exports.PUBLIC_ROLE, INTRA_SITE: exports.INTRA_SITE_ROLE }; // ============ Chain Configuration ============ /** * Master chain ID - currently set to Sepolia testnet * Chain ID 11155111 for Ethereum Sepolia testnet */ exports.MASTER_CHAIN_ID = 11155111; // ============ Origins Presets ============ /** * Creates an origins array with exactly getMethodCount() elements * @param role The role to assign to all methods * @returns Origins array suitable for CORSPolicy */ function createOriginsArray(role) { return new Array(getMethodCount()).fill(role); } /** * Creates an origins array with different roles for read vs write operations * @param readRole Role for read operations (HEAD, GET, OPTIONS, LOCATE) * @param writeRole Role for write operations (POST, PUT, PATCH, DELETE, DEFINE) * @returns Origins array with mixed access */ function createMixedOriginsArray(readRole, writeRole) { const origins = new Array(getMethodCount()); origins[Method.HEAD] = readRole; origins[Method.GET] = readRole; origins[Method.POST] = writeRole; origins[Method.PUT] = writeRole; origins[Method.PATCH] = writeRole; origins[Method.DELETE] = writeRole; origins[Method.OPTIONS] = readRole; origins[Method.LOCATE] = readRole; origins[Method.DEFINE] = writeRole; return origins; } /** * Origins preset: All methods public */ exports.ORIGINS_PUBLIC = createOriginsArray(exports.PUBLIC_ROLE); /** * Origins preset: All methods admin only */ exports.ORIGINS_ADMIN_ONLY = createOriginsArray(exports.DEFAULT_ADMIN_ROLE); /** * Origins preset: All methods blacklisted (denied) */ exports.ORIGINS_BLACKLISTED = createOriginsArray(exports.BLACKLIST_ROLE); /** * Origins preset: All methods for intra-site communication */ exports.ORIGINS_INTRA_SITE = createOriginsArray(exports.INTRA_SITE_ROLE); /** * Origins preset: Read methods public, write methods admin */ exports.ORIGINS_READ_PUBLIC_WRITE_ADMIN = createMixedOriginsArray(exports.PUBLIC_ROLE, exports.DEFAULT_ADMIN_ROLE); /** * Origins preset: Read methods public, write methods intra-site */ exports.ORIGINS_READ_PUBLIC_WRITE_INTRA = createMixedOriginsArray(exports.PUBLIC_ROLE, exports.INTRA_SITE_ROLE); /** * Origins preset: Read methods public, write methods blacklisted */ exports.ORIGINS_READ_ONLY_PUBLIC = createMixedOriginsArray(exports.PUBLIC_ROLE, exports.BLACKLIST_ROLE); /** * Origins preset: API pattern - read public, post/patch intra-site, put/delete/define admin */ exports.ORIGINS_API_PATTERN = (() => { const origins = new Array(getMethodCount()); origins[Method.HEAD] = exports.PUBLIC_ROLE; origins[Method.GET] = exports.PUBLIC_ROLE; origins[Method.POST] = exports.INTRA_SITE_ROLE; origins[Method.PUT] = exports.DEFAULT_ADMIN_ROLE; origins[Method.PATCH] = exports.INTRA_SITE_ROLE; origins[Method.DELETE] = exports.DEFAULT_ADMIN_ROLE; origins[Method.OPTIONS] = exports.PUBLIC_ROLE; origins[Method.LOCATE] = exports.PUBLIC_ROLE; origins[Method.DEFINE] = exports.DEFAULT_ADMIN_ROLE; return origins; })(); /** * Origins preset: Immutable content - read public, patch/delete blacklisted, others admin */ exports.ORIGINS_IMMUTABLE_CONTENT = (() => { const origins = new Array(getMethodCount()); origins[Method.HEAD] = exports.PUBLIC_ROLE; origins[Method.GET] = exports.PUBLIC_ROLE; origins[Method.POST] = exports.DEFAULT_ADMIN_ROLE; origins[Method.PUT] = exports.DEFAULT_ADMIN_ROLE; origins[Method.PATCH] = exports.BLACKLIST_ROLE; // Immutable content can't be patched origins[Method.DELETE] = exports.BLACKLIST_ROLE; // Immutable content can't be deleted origins[Method.OPTIONS] = exports.PUBLIC_ROLE; origins[Method.LOCATE] = exports.PUBLIC_ROLE; origins[Method.DEFINE] = exports.DEFAULT_ADMIN_ROLE; return origins; })(); // ============ Origins Presets Collection ============ /** * Collection of all origins presets for easy access */ exports.ORIGINS_PRESETS = { PUBLIC: exports.ORIGINS_PUBLIC, ADMIN_ONLY: exports.ORIGINS_ADMIN_ONLY, BLACKLISTED: exports.ORIGINS_BLACKLISTED, INTRA_SITE: exports.ORIGINS_INTRA_SITE, READ_PUBLIC_WRITE_ADMIN: exports.ORIGINS_READ_PUBLIC_WRITE_ADMIN, READ_PUBLIC_WRITE_INTRA: exports.ORIGINS_READ_PUBLIC_WRITE_INTRA, READ_ONLY_PUBLIC: exports.ORIGINS_READ_ONLY_PUBLIC, API_PATTERN: exports.ORIGINS_API_PATTERN, IMMUTABLE_CONTENT: exports.ORIGINS_IMMUTABLE_CONTENT }; // ============ Default Headers ============ /** * Fully public header - allows all methods for all users * Uses PUBLIC_ROLE for all method access */ exports.PUBLIC_HEADER = { cache: { immutableFlag: false, preset: 2, // CachePreset.DEFAULT custom: "" }, cors: { methods: exports.ALL_METHODS_BITMASK, origins: exports.ORIGINS_PUBLIC, preset: 1, // CORSPreset.PUBLIC custom: "" }, redirect: { code: 0, location: "" } }; /** * Admin-only header - restricts all methods to admin role * Only admins can access any methods */ exports.ADMIN_ONLY_HEADER = { cache: { immutableFlag: false, preset: 0, // CachePreset.NONE custom: "" }, cors: { methods: exports.ALL_METHODS_BITMASK, origins: exports.ORIGINS_ADMIN_ONLY, preset: 5, // CORSPreset.PRIVATE custom: "" }, redirect: { code: 0, location: "" } }; /** * Read-only public header - allows read operations for public, write operations for admins * Balanced access control for content sites */ exports.READ_ONLY_PUBLIC_HEADER = { cache: { immutableFlag: false, preset: 3, // CachePreset.SHORT custom: "" }, cors: { methods: exports.ALL_METHODS_BITMASK, origins: exports.ORIGINS_READ_PUBLIC_WRITE_ADMIN, preset: 1, // CORSPreset.PUBLIC custom: "" }, redirect: { code: 0, location: "" } }; /** * API header - designed for API endpoints with mixed access patterns * Read operations public, write operations restricted */ exports.API_HEADER = { cache: { immutableFlag: false, preset: 1, // CachePreset.NO_CACHE custom: "" }, cors: { methods: exports.ALL_METHODS_BITMASK, origins: exports.ORIGINS_API_PATTERN, preset: 3, // CORSPreset.API custom: "" }, redirect: { code: 0, location: "" } }; /** * Intra-site communication header - for internal service communication * Only allows intra-site role and admin access */ exports.INTRA_SITE_HEADER = { cache: { immutableFlag: false, preset: 1, // CachePreset.NO_CACHE - don't cache internal communications custom: "" }, cors: { methods: exports.ALL_METHODS_BITMASK, origins: exports.ORIGINS_INTRA_SITE, preset: 5, // CORSPreset.PRIVATE custom: "" }, redirect: { code: 0, location: "" } }; /** * Immutable public content header - for permanent, cacheable public content * Content that never changes and can be cached indefinitely */ exports.IMMUTABLE_PUBLIC_HEADER = { cache: { immutableFlag: true, preset: 6, // CachePreset.PERMANENT custom: "" }, cors: { methods: exports.ALL_METHODS_BITMASK, origins: exports.ORIGINS_IMMUTABLE_CONTENT, preset: 1, // CORSPreset.PUBLIC custom: "" }, redirect: { code: 0, location: "" } }; /** * Read-only public header with limited methods - only allows read operations * Completely prevents write operations by not including them in methods bitmask */ exports.STRICT_READ_ONLY_HEADER = { cache: { immutableFlag: false, preset: 4, // CachePreset.MEDIUM custom: "" }, cors: { methods: exports.READ_ONLY_METHODS_BITMASK, // Only read methods enabled origins: exports.ORIGINS_READ_ONLY_PUBLIC, preset: 1, // CORSPreset.PUBLIC custom: "" }, redirect: { code: 0, location: "" } }; // ============ Header Collections ============ /** * Collection of all default headers for easy access */ exports.DEFAULT_HEADERS = { PUBLIC: exports.PUBLIC_HEADER, ADMIN_ONLY: exports.ADMIN_ONLY_HEADER, READ_ONLY_PUBLIC: exports.READ_ONLY_PUBLIC_HEADER, API: exports.API_HEADER, INTRA_SITE: exports.INTRA_SITE_HEADER, IMMUTABLE_PUBLIC: exports.IMMUTABLE_PUBLIC_HEADER, STRICT_READ_ONLY: exports.STRICT_READ_ONLY_HEADER }; /** * Default header to use when no specific header is specified * Uses read-only public access pattern as a sensible default */ exports.DEFAULT_HEADER = exports.READ_ONLY_PUBLIC_HEADER; // ============ Helper Functions ============ /** * Creates a custom header with specified parameters * @param options Header configuration options * @returns Complete HeaderInfoStruct */ function createCustomHeader(options) { const { methods = [Method.HEAD, Method.GET, Method.OPTIONS, Method.LOCATE], origins = exports.ORIGINS_READ_PUBLIC_WRITE_ADMIN, cachePreset = 2, // CachePreset.DEFAULT corsPreset = 4, // CORSPreset.MIXED_ACCESS immutable = false, redirectCode = 0, redirectLocation = "", customCache = "", customCors = "" } = options; // Ensure origins array has correct length const normalizedOrigins = origins.length === getMethodCount() ? origins : createOriginsArray(origins[0] || exports.PUBLIC_ROLE); return { cache: { immutableFlag: immutable, preset: cachePreset, custom: customCache }, cors: { methods: methodsToBitmask(methods), origins: normalizedOrigins, preset: corsPreset, custom: customCors }, redirect: { code: redirectCode, location: redirectLocation } }; } //# sourceMappingURL=constants.js.map