Skip to content

Commit b171510

Browse files
committed
several updates
1 parent 70caec2 commit b171510

File tree

6 files changed

+241
-81
lines changed

6 files changed

+241
-81
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ site/.vitepress/cache/
44

55
# Local Netlify folder
66
.netlify
7+
output/output.har

README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@ This tool is created to check the SCIM (System for Cross-domain Identity Managem
66

77
## Usage
88

9-
~~~
10-
CONFIG_FILE=./site/.vitepress/theme/components/config.yaml \
11-
AUTH_HEADER="Bearer REPLACE_THIS" \
12-
BASE_URL="https://api.scim.dev/scim/v2" \
13-
HAR_FILE_NAME="/output/output.har" \
14-
node --test
15-
~~~
9+
You can use SCIM Verify directly with npx without installing it globally:
10+
11+
```bash
12+
npx scimverify --base-url https://api.scim.dev/scim/v2 --auth-header "Bearer YOUR_TOKEN" --config ./config.yaml
13+
```
14+
15+
Options:
16+
- `-b, --base-url <url>` - Base URL of the SCIM server (required)
17+
- `-a, --auth-header <auth>` - Authorization header (required)
18+
- `-c, --config <path>` - Path to YAML configuration file (optional)
19+
- `-o, --har-file <path>` - Path to write HAR file output (optional)
20+
- `-h, --help` - Show help message
1621

1722
## Features
1823

bin/scimverify.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env node
2+
3+
import { runAllTests } from '../index.js';
4+
import { parse } from 'yaml';
5+
import fs from 'fs/promises';
6+
import path from 'path';
7+
import { fileURLToPath } from 'url';
8+
import { writeHarFile, clearHarEntries } from '../src/helpers.js';
9+
10+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
11+
12+
// Parse command line arguments
13+
const args = process.argv.slice(2);
14+
let configPath = null;
15+
let baseUrl = null;
16+
let authHeader = null;
17+
let harFileName = null;
18+
19+
// Simple argument parser
20+
for (let i = 0; i < args.length; i++) {
21+
const arg = args[i];
22+
if (arg === '--config' || arg === '-c') {
23+
configPath = args[++i];
24+
} else if (arg === '--base-url' || arg === '-b') {
25+
baseUrl = args[++i];
26+
} else if (arg === '--auth-header' || arg === '-a') {
27+
authHeader = args[++i];
28+
} else if (arg === '--har-file' || arg === '-o') {
29+
harFileName = args[++i];
30+
} else if (arg === '--help' || arg === '-h') {
31+
printHelp();
32+
process.exit(0);
33+
}
34+
}
35+
36+
function printHelp() {
37+
console.log(`
38+
SCIM Verify - A tool to verify SCIM server implementations
39+
40+
Usage: npx scimverify [options]
41+
42+
Options:
43+
-c, --config <path> Path to YAML configuration file
44+
-b, --base-url <url> Base URL of the SCIM server
45+
-a, --auth-header <auth> Authorization header (e.g. "Bearer token")
46+
-o, --har-file <path> Path to write HAR file output
47+
-h, --help Show this help message
48+
49+
Example:
50+
npx scimverify --base-url https://api.scim.dev/scim/v2 --auth-header "Bearer token123" --config ./config.yaml
51+
52+
Documentation: https://verify.scim.dev
53+
`);
54+
}
55+
56+
// Main function
57+
async function main() {
58+
// Check for required parameters
59+
if (!baseUrl) {
60+
console.error('Error: Base URL is required. Use --base-url or -b option.');
61+
printHelp();
62+
process.exit(1);
63+
}
64+
65+
if (!authHeader) {
66+
console.error('Error: Authorization header is required. Use --auth-header or -a option.');
67+
printHelp();
68+
process.exit(1);
69+
}
70+
71+
// Load config from file if provided
72+
let config = {};
73+
if (configPath) {
74+
try {
75+
const configFile = await fs.readFile(path.resolve(process.cwd(), configPath), 'utf8');
76+
config = parse(configFile);
77+
} catch (error) {
78+
console.error(`Error loading config file: ${error.message}`);
79+
process.exit(1);
80+
}
81+
}
82+
83+
// Run tests
84+
try {
85+
const result = await runAllTests({
86+
baseURL: baseUrl,
87+
authHeader: authHeader,
88+
...config,
89+
});
90+
91+
if (!result.success) {
92+
console.error('Tests failed!');
93+
process.exit(1);
94+
} else {
95+
console.log('All tests passed successfully!');
96+
}
97+
} catch (error) {
98+
console.error('Error running tests:', error);
99+
process.exit(1);
100+
} finally {
101+
if (harFileName) {
102+
// Make sure the HAR file has the correct extension
103+
if (!harFileName.toLowerCase().endsWith('.har')) {
104+
harFileName += '.har';
105+
}
106+
107+
console.log('Writing HAR file:', harFileName);
108+
writeHarFile(harFileName);
109+
}
110+
clearHarEntries();
111+
}
112+
}
113+
114+
main().catch(error => {
115+
console.error('Unexpected error:', error);
116+
process.exit(1);
117+
});

index.js

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
1-
import { run } from 'node:test';
2-
import path from 'path';
3-
import { fileURLToPath } from 'url';
1+
// Main entry point for the scimverify package
2+
import { runAllTests } from './scim.test.js';
3+
import runBasicTests from './src/basics.js';
4+
import runUserTests from './src/users.js';
5+
import runGroupTests from './src/groups.js';
6+
import runResourceTypeTests from './src/resourcetypes.js';
7+
import { runTests as runSchemaTests } from './src/schemas.js';
8+
import { getAxiosInstance, writeHarFile, clearHarEntries } from './src/helpers.js';
49

10+
// Export main functionality
11+
export {
12+
runAllTests,
13+
runBasicTests,
14+
runUserTests,
15+
runGroupTests,
16+
runResourceTypeTests,
17+
runSchemaTests,
18+
getAxiosInstance,
19+
writeHarFile,
20+
clearHarEntries
21+
};
522

6-
const __filename = fileURLToPath(import.meta.url);
7-
const __dirname = path.dirname(__filename);
8-
9-
// Run tests sequentially and pipe directly to NDJSON reporter and stdout
10-
run({
11-
files: [path.resolve(__dirname, 'scim.test.js')],
12-
concurrency: 1,
13-
reporter: 'spec'
14-
}).on('test:fail', () => {
15-
process.exitCode = 1;
16-
})
17-
.pipe(process.stdout);
23+
// Default export for convenience
24+
export default runAllTests;

package.json

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,22 @@
22
"name": "scimverify",
33
"version": "1.0.0",
44
"description": "SCIM Verification Tool",
5-
"main": "server.js",
5+
"main": "index.js",
6+
"bin": {
7+
"scimverify": "./bin/scimverify.js"
8+
},
9+
"exports": {
10+
".": "./index.js",
11+
"./test": "./scim.test.js"
12+
},
613
"scripts": {
714
"start": "node server.js",
8-
"local": "node scim.test.js"
15+
"local": "node scim.test.js",
16+
"test": "node scim.test.js",
17+
"prepublishOnly": "npm test",
18+
"publish": "npm publish --access public"
919
},
10-
"author": "",
20+
"author": "limosa-io",
1121
"license": "GPL-3.0-only",
1222
"homepage": "https://verify.scim.dev",
1323
"repository": {
@@ -18,29 +28,46 @@
1828
"url": "https://github.com/limosa-io/scimverify/issues"
1929
},
2030
"dependencies": {
31+
"axios": "^1.7.7",
32+
"yaml": "^2.7.0"
33+
},
34+
"peerDependencies": {
35+
"ajv": "^8.17.1"
36+
},
37+
"devDependencies": {
38+
"ajv": "^8.17.1"
39+
},
40+
"optionalDependencies": {
2141
"@codemirror/lang-yaml": "^6.1.2",
2242
"@codemirror/state": "^6.5.2",
2343
"@codemirror/theme-one-dark": "^6.1.2",
2444
"@codemirror/view": "^6.36.4",
25-
"ajv": "^8.17.1",
26-
"axios": "^1.7.7",
2745
"codemirror": "^6.0.1",
2846
"cors": "^2.8.5",
2947
"dotenv": "^16.4.5",
3048
"express": "^4.18.2",
3149
"js-yaml": "^4.1.0",
3250
"socket.io": "^4.8.1",
33-
"socket.io-client": "^4.7.4",
34-
"yaml": "^2.7.0"
35-
},
36-
"devDependencies": {
37-
51+
"socket.io-client": "^4.7.4"
3852
},
3953
"type": "module",
4054
"directories": {
4155
"doc": "doc"
4256
},
43-
"keywords": ["scim", "verification", "testing", "api"],
57+
"keywords": ["scim", "verification", "testing", "api", "system for cross-domain identity management"],
58+
"files": [
59+
"index.js",
60+
"scim.test.js",
61+
"src/**/*.js",
62+
"src/**/*.json",
63+
"src/**/*.yaml",
64+
"bin/*.js",
65+
"LICENSE.md",
66+
"README.md"
67+
],
68+
"engines": {
69+
"node": ">=16.0.0"
70+
},
4471
"links": {
4572
"website": "https://scim.dev",
4673
"verification": "https://verify.scim.dev"

scim.test.js

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -76,62 +76,65 @@ export async function runAllTests(config) {
7676
}
7777
}
7878

79-
if (process.env.CONFIG_FILE) {
80-
// If a config file is provided, read it and parse it
81-
const configFilePath = path.resolve(process.cwd(), process.env.CONFIG_FILE);
82-
process.env.CONFIG = await fs.readFile(configFilePath, 'utf8');
83-
}
84-
85-
if (!process.env.CONFIG) {
86-
// If no config file is provided, check if the config is passed as an environment variable
87-
console.error('No CONFIG or CONFIG_FILE environment variable provided. Exiting.');
88-
process.exit(1);
89-
}
79+
// Check if this file is being run directly
80+
if (import.meta.url === `file://${process.argv[1]}`) {
81+
if (process.env.CONFIG_FILE) {
82+
// If a config file is provided, read it and parse it
83+
const configFilePath = path.resolve(process.cwd(), process.env.CONFIG_FILE);
84+
process.env.CONFIG = await fs.readFile(configFilePath, 'utf8');
85+
}
9086

91-
try {
92-
parse(process.env.CONFIG);
93-
} catch (error) {
94-
console.error('Invalid YAML configuration provided:', error.message);
95-
process.exit(1);
96-
}
87+
if (!process.env.CONFIG) {
88+
// If no config file is provided, check if the config is passed as an environment variable
89+
console.error('No CONFIG or CONFIG_FILE environment variable provided. Exiting.');
90+
process.exit(1);
91+
}
9792

98-
// Check if the configuration is valid
99-
if (!process.env.BASE_URL) {
100-
console.error('Environment variable BASE_URL is required');
101-
process.exit(1);
102-
}
103-
if (!process.env.AUTH_HEADER) {
104-
console.error('Environment variable AUTH_HEADER is required');
105-
process.exit(1);
106-
}
93+
try {
94+
parse(process.env.CONFIG);
95+
} catch (error) {
96+
console.error('Invalid YAML configuration provided:', error.message);
97+
process.exit(1);
98+
}
10799

108-
// Run the tests by default when the file is imported
109-
runAllTests(
110-
{
111-
baseURL: process.env.BASE_URL,
112-
authHeader: process.env.AUTH_HEADER,
113-
...parse(process.env.CONFIG),
100+
// Check if the configuration is valid
101+
if (!process.env.BASE_URL) {
102+
console.error('Environment variable BASE_URL is required');
103+
process.exit(1);
114104
}
115-
).then((result) => {
116-
if (!result.success) {
105+
if (!process.env.AUTH_HEADER) {
106+
console.error('Environment variable AUTH_HEADER is required');
117107
process.exit(1);
118108
}
119-
}).catch((error) => {
120-
console.error('Error running tests:', error);
121-
process.exit(1);
122-
}).finally(() => {
123-
if(process.env.HAR_FILE_NAME) {
124-
// Make sure the HAR file has the correct extension
125-
let harFileName = process.env.HAR_FILE_NAME;
126-
if (!harFileName.toLowerCase().endsWith('.har')) {
127-
harFileName += '.har';
109+
110+
// Run the tests by default when the file is imported
111+
runAllTests(
112+
{
113+
baseURL: process.env.BASE_URL,
114+
authHeader: process.env.AUTH_HEADER,
115+
...parse(process.env.CONFIG),
128116
}
117+
).then((result) => {
118+
if (!result.success) {
119+
process.exit(1);
120+
}
121+
}).catch((error) => {
122+
console.error('Error running tests:', error);
123+
process.exit(1);
124+
}).finally(() => {
125+
if(process.env.HAR_FILE_NAME) {
126+
// Make sure the HAR file has the correct extension
127+
let harFileName = process.env.HAR_FILE_NAME;
128+
if (!harFileName.toLowerCase().endsWith('.har')) {
129+
harFileName += '.har';
130+
}
129131

130-
console.log('Writing HAR file:', harFileName);
132+
console.log('Writing HAR file:', harFileName);
131133

132-
writeHarFile(harFileName);
133-
}
134+
writeHarFile(harFileName);
135+
}
134136

135-
clearHarEntries();
137+
clearHarEntries();
136138

137-
});
139+
});
140+
}

0 commit comments

Comments
 (0)