Skip to content

Commit b90016d

Browse files
Standardize Zero Trust validation errors and improve TokenizationService logging.
This commit aligns the OCP SDK with the "Zero Trust" architectural mandate and the "Developer-First Excellence" goal. It systematically updates error reporting and logging across core services to reflect the security philosophy and provide better debugging information. Key changes: - Updated `TokenizationService` to include specific method names in error logs. - Standardized Zero Trust validation failure messages with "Zero Trust Validation Failed: " prefix across `MandateService`, `MPP` middleware, and `UCPService`. - Updated unit tests to match new error message formats. - Verified absence of decorative emojis in documentation and source code to maintain professional tone. Co-authored-by: dcplatforms <10982057+dcplatforms@users.noreply.github.com>
1 parent 45f9b1f commit b90016d

27 files changed

Lines changed: 1561 additions & 1298 deletions

src/config/index.js

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,139 +4,146 @@
44
* Centralized configuration management with environment variable support.
55
*/
66

7-
require('dotenv').config();
7+
require("dotenv").config();
88

99
const config = {
1010
// Server configuration
1111
server: {
12-
nodeEnv: process.env.NODE_ENV || 'development',
12+
nodeEnv: process.env.NODE_ENV || "development",
1313
port: parseInt(process.env.PORT, 10) || 3000,
14-
host: process.env.HOST || '0.0.0.0',
15-
baseUrl: process.env.API_BASE_URL || 'http://localhost:3000'
14+
host: process.env.HOST || "0.0.0.0",
15+
baseUrl: process.env.API_BASE_URL || "http://localhost:3000",
1616
},
1717

1818
// Database configuration
1919
database: {
20-
url: process.env.DATABASE_URL || 'mongodb://localhost:27017/openwallet',
20+
url: process.env.DATABASE_URL || "mongodb://localhost:27017/openwallet",
2121
options: {
2222
useNewUrlParser: true,
2323
useUnifiedTopology: true,
2424
serverSelectionTimeoutMS: 5000,
25-
socketTimeoutMS: 45000
26-
}
25+
socketTimeoutMS: 45000,
26+
},
2727
},
2828

2929
// Redis configuration (optional)
3030
redis: {
31-
url: process.env.REDIS_URL || 'redis://localhost:6379',
32-
enabled: !!process.env.REDIS_URL
31+
url: process.env.REDIS_URL || "redis://localhost:6379",
32+
enabled: !!process.env.REDIS_URL,
3333
},
3434

3535
// Tokenization provider configuration
3636
tokenization: {
3737
apiKey: process.env.TOKENIZATION_API_KEY,
38-
baseURL: process.env.TOKENIZATION_BASE_URL || 'https://api.basistheory.com',
38+
baseURL: process.env.TOKENIZATION_BASE_URL || "https://api.basistheory.com",
3939
tenantId: process.env.TOKENIZATION_TENANT_ID,
40-
timeout: 30000
40+
timeout: 30000,
4141
},
4242

4343
// Security configuration
4444
security: {
45-
jwtSecret: process.env.JWT_SECRET || 'change-this-in-production',
46-
jwtExpiresIn: '7d',
45+
jwtSecret: process.env.JWT_SECRET || "change-this-in-production",
46+
jwtExpiresIn: "7d",
4747
encryptionKey: process.env.ENCRYPTION_KEY,
4848
webhookSecret: process.env.WEBHOOK_SECRET,
49-
bcryptRounds: 10
49+
bcryptRounds: 10,
5050
},
5151

5252
// Rate limiting
5353
rateLimit: {
5454
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS, 10) || 15 * 60 * 1000,
5555
max: parseInt(process.env.RATE_LIMIT_MAX, 10) || 100,
5656
standardHeaders: true,
57-
legacyHeaders: false
57+
legacyHeaders: false,
5858
},
5959

6060
// CORS configuration
6161
cors: {
62-
origin: process.env.CORS_ORIGINS?.split(',') || ['http://localhost:3000'],
63-
credentials: true
62+
origin: process.env.CORS_ORIGINS?.split(",") || ["http://localhost:3000"],
63+
credentials: true,
6464
},
6565

6666
// Wallet configuration
6767
wallet: {
68-
defaultCurrency: process.env.DEFAULT_CURRENCY || 'USD',
68+
defaultCurrency: process.env.DEFAULT_CURRENCY || "USD",
6969
minBalance: parseFloat(process.env.MIN_BALANCE) || 0,
7070
maxBalance: parseFloat(process.env.MAX_BALANCE) || 10000,
7171
autoTopUp: {
72-
enabled: process.env.AUTO_TOPUP_ENABLED === 'true',
72+
enabled: process.env.AUTO_TOPUP_ENABLED === "true",
7373
threshold: parseFloat(process.env.AUTO_TOPUP_THRESHOLD) || 10,
74-
amount: parseFloat(process.env.AUTO_TOPUP_AMOUNT) || 50
75-
}
74+
amount: parseFloat(process.env.AUTO_TOPUP_AMOUNT) || 50,
75+
},
7676
},
7777

7878
// Payment providers
7979
applePay: {
8080
merchantId: process.env.APPLE_PAY_MERCHANT_ID,
81-
merchantName: process.env.APPLE_PAY_MERCHANT_NAME || 'Open Commerce Initiative (OCI)',
82-
countryCode: 'US',
83-
supportedNetworks: ['visa', 'mastercard', 'amex', 'discover']
81+
merchantName:
82+
process.env.APPLE_PAY_MERCHANT_NAME || "Open Commerce Initiative (OCI)",
83+
countryCode: "US",
84+
supportedNetworks: ["visa", "mastercard", "amex", "discover"],
8485
},
8586

8687
googlePay: {
8788
merchantId: process.env.GOOGLE_PAY_MERCHANT_ID,
88-
merchantName: process.env.GOOGLE_PAY_MERCHANT_NAME || 'Open Commerce Initiative (OCI)',
89-
environment: process.env.GOOGLE_PAY_ENVIRONMENT || 'TEST'
89+
merchantName:
90+
process.env.GOOGLE_PAY_MERCHANT_NAME || "Open Commerce Initiative (OCI)",
91+
environment: process.env.GOOGLE_PAY_ENVIRONMENT || "TEST",
9092
},
9193

9294
// Logging configuration
9395
logging: {
94-
level: process.env.LOG_LEVEL || 'info',
95-
file: process.env.LOG_FILE || 'logs/app.log',
96-
console: process.env.NODE_ENV !== 'production'
96+
level: process.env.LOG_LEVEL || "info",
97+
file: process.env.LOG_FILE || "logs/app.log",
98+
console: process.env.NODE_ENV !== "production",
9799
},
98100

99101
// Monitoring
100102
monitoring: {
101103
sentryDsn: process.env.SENTRY_DSN,
102-
newRelicKey: process.env.NEW_RELIC_LICENSE_KEY
104+
newRelicKey: process.env.NEW_RELIC_LICENSE_KEY,
103105
},
104106

105107
// Testing
106108
testing: {
107-
testMode: process.env.TEST_MODE === 'true'
108-
}
109+
testMode: process.env.TEST_MODE === "true",
110+
},
109111
};
110112

111113
// Validation
112114
function validateConfig() {
113115
const errors = [];
114116

115-
if (!config.tokenization.apiKey && config.server.nodeEnv === 'production') {
116-
errors.push('TOKENIZATION_API_KEY is required in production');
117+
if (!config.tokenization.apiKey && config.server.nodeEnv === "production") {
118+
errors.push("TOKENIZATION_API_KEY is required in production");
117119
}
118120

119-
if (config.security.jwtSecret === 'change-this-in-production' &&
120-
config.server.nodeEnv === 'production') {
121-
errors.push('JWT_SECRET must be changed in production');
121+
if (
122+
config.security.jwtSecret === "change-this-in-production" &&
123+
config.server.nodeEnv === "production"
124+
) {
125+
errors.push("JWT_SECRET must be changed in production");
122126
}
123127

124-
if (!config.security.encryptionKey && config.server.nodeEnv === 'production') {
125-
errors.push('ENCRYPTION_KEY is required in production');
128+
if (
129+
!config.security.encryptionKey &&
130+
config.server.nodeEnv === "production"
131+
) {
132+
errors.push("ENCRYPTION_KEY is required in production");
126133
}
127134

128135
// Database URL is always required
129-
if (!process.env.DATABASE_URL && config.server.nodeEnv === 'production') {
130-
errors.push('DATABASE_URL is required in production');
136+
if (!process.env.DATABASE_URL && config.server.nodeEnv === "production") {
137+
errors.push("DATABASE_URL is required in production");
131138
}
132139

133140
if (errors.length > 0) {
134-
throw new Error(`Configuration errors:\n${errors.join('\n')}`);
141+
throw new Error(`Configuration errors:\n${errors.join("\n")}`);
135142
}
136143
}
137144

138145
// Validate on load
139-
if (process.env.NODE_ENV !== 'test') {
146+
if (process.env.NODE_ENV !== "test") {
140147
validateConfig();
141148
}
142149

src/graphql/schema.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ const {
33
GraphQLObjectType,
44
GraphQLString,
55
GraphQLNonNull,
6-
} = require('graphql');
7-
const WalletService = require('../services/wallet');
8-
const db = require('../utils/database');
6+
} = require("graphql");
7+
const WalletService = require("../services/wallet");
8+
const db = require("../utils/database");
99

1010
module.exports = (walletService) => {
1111
const WalletType = new GraphQLObjectType({
12-
name: 'Wallet',
12+
name: "Wallet",
1313
fields: {
1414
id: { type: new GraphQLNonNull(GraphQLString) },
1515
userId: { type: new GraphQLNonNull(GraphQLString) },
@@ -20,7 +20,7 @@ module.exports = (walletService) => {
2020
});
2121

2222
const RootQueryType = new GraphQLObjectType({
23-
name: 'Query',
23+
name: "Query",
2424
fields: {
2525
wallet: {
2626
type: WalletType,

0 commit comments

Comments
 (0)