@lawpath-tech/npm-auth 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - uses: actions/setup-node@v4
15
+ with:
16
+ node-version: '20'
17
+ registry-url: 'https://registry.npmjs.org'
18
+
19
+ - run: npm publish --access public
20
+ env:
21
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/bin/cli.js ADDED
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ /**
7
+ * Parse .npmrc content and extract key-value pairs
8
+ * @param {string} content - .npmrc file content
9
+ * @returns {Object} - Parsed key-value pairs
10
+ */
11
+ function parseNpmrc(content) {
12
+ const config = {};
13
+ const lines = content.split('\n');
14
+
15
+ for (const line of lines) {
16
+ const trimmed = line.trim();
17
+ // Skip comments and empty lines
18
+ if (!trimmed || trimmed.startsWith('#')) continue;
19
+
20
+ const match = trimmed.match(/^([^=]+)=(.*)$/);
21
+ if (match) {
22
+ config[match[1].trim()] = match[2].trim();
23
+ }
24
+ }
25
+
26
+ return config;
27
+ }
28
+
29
+ async function main() {
30
+ console.log('Lawpath npm authentication setup\n');
31
+
32
+ // Skip in CI environment
33
+ if (process.env.CI) {
34
+ console.log('CI environment detected, skipping...');
35
+ process.exit(0);
36
+ }
37
+
38
+ const npmrcPath = path.join(process.cwd(), '.npmrc');
39
+
40
+ // Read current .npmrc
41
+ let npmrc = '';
42
+ try {
43
+ npmrc = fs.readFileSync(npmrcPath, 'utf-8');
44
+ } catch (e) {
45
+ console.error('Error: No .npmrc found in current directory.');
46
+ console.error('Create a .npmrc file with the following:');
47
+ console.error('\n lp_npm_token_url=<api-endpoint>');
48
+ console.error(' lp_auth_token=<your-token>\n');
49
+ process.exit(1);
50
+ }
51
+
52
+ // Parse .npmrc
53
+ const config = parseNpmrc(npmrc);
54
+
55
+ // Validate required fields
56
+ if (!config.lp_npm_token_url) {
57
+ console.error('Error: Missing lp_npm_token_url in .npmrc');
58
+ console.error('Add the following line to your .npmrc:');
59
+ console.error('\n lp_npm_token_url=<api-endpoint>\n');
60
+ process.exit(1);
61
+ }
62
+
63
+ if (!config.lp_auth_token) {
64
+ console.error('Error: Missing lp_auth_token in .npmrc');
65
+ console.error('Add the following line to your .npmrc:');
66
+ console.error('\n lp_auth_token=<your-token>\n');
67
+ process.exit(1);
68
+ }
69
+
70
+ const apiUrl = config.lp_npm_token_url;
71
+ const lpToken = config.lp_auth_token;
72
+
73
+ console.log('Found configuration in .npmrc:');
74
+ console.log(` lp_npm_token_url: ${apiUrl}`);
75
+ console.log(` lp_auth_token: ${lpToken.substring(0, 8)}...`);
76
+ console.log('\nFetching npm token from Lawpath config API...\n');
77
+
78
+ try {
79
+ // Build URL with token as query param
80
+ const url = new URL(apiUrl);
81
+ url.searchParams.set('token', lpToken);
82
+
83
+ const response = await fetch(url.toString(), {
84
+ headers: {
85
+ 'Authorization': `Bearer ${lpToken}`,
86
+ 'Content-Type': 'application/json'
87
+ }
88
+ });
89
+
90
+ if (!response.ok) {
91
+ if (response.status === 401) {
92
+ console.error('Error: Invalid or expired lp_auth_token');
93
+ console.error('Please contact your administrator for a new token.');
94
+ } else {
95
+ console.error(`Error: API returned status ${response.status}`);
96
+ }
97
+ process.exit(1);
98
+ }
99
+
100
+ const { npmToken } = await response.json();
101
+
102
+ if (!npmToken) {
103
+ console.error('Error: No npm token received from API');
104
+ process.exit(1);
105
+ }
106
+
107
+ // Update .npmrc with npm token
108
+ const authLine = `//registry.npmjs.org/:_authToken=${npmToken}`;
109
+
110
+ if (npmrc.includes('registry.npmjs.org')) {
111
+ npmrc = npmrc.replace(
112
+ /\/\/registry\.npmjs\.org\/:_authToken=.*/,
113
+ authLine
114
+ );
115
+ } else {
116
+ npmrc = npmrc.trim() + `\n${authLine}\n`;
117
+ }
118
+
119
+ fs.writeFileSync(npmrcPath, npmrc);
120
+
121
+ console.log('Successfully configured npm authentication');
122
+ console.log('You can now run: npm install\n');
123
+
124
+ } catch (error) {
125
+ console.error('Error fetching npm token:', error.message);
126
+ process.exit(1);
127
+ }
128
+ }
129
+
130
+ main();
package/index.js ADDED
@@ -0,0 +1,108 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * Parse .npmrc content and extract key-value pairs
6
+ * @param {string} content - .npmrc file content
7
+ * @returns {Object} - Parsed key-value pairs
8
+ */
9
+ function parseNpmrc(content) {
10
+ const config = {};
11
+ const lines = content.split('\n');
12
+
13
+ for (const line of lines) {
14
+ const trimmed = line.trim();
15
+ // Skip comments and empty lines
16
+ if (!trimmed || trimmed.startsWith('#')) continue;
17
+
18
+ const match = trimmed.match(/^([^=]+)=(.*)$/);
19
+ if (match) {
20
+ config[match[1].trim()] = match[2].trim();
21
+ }
22
+ }
23
+
24
+ return config;
25
+ }
26
+
27
+ /**
28
+ * Configure npm authentication for Lawpath private packages
29
+ * Reads lp_npm_token_url and lp_auth_token from .npmrc
30
+ * @param {Object} options
31
+ * @param {string} options.npmrcPath - Path to .npmrc file (defaults to cwd)
32
+ * @returns {Promise<void>}
33
+ */
34
+ async function configureNpmAuth(options = {}) {
35
+ const {
36
+ npmrcPath = path.join(process.cwd(), '.npmrc')
37
+ } = options;
38
+
39
+ // Skip in CI environment
40
+ if (process.env.CI) {
41
+ console.log('CI environment detected, skipping npm auth setup');
42
+ return;
43
+ }
44
+
45
+ // Read current .npmrc
46
+ let npmrc;
47
+ try {
48
+ npmrc = fs.readFileSync(npmrcPath, 'utf-8');
49
+ } catch (e) {
50
+ throw new Error(`No .npmrc found at ${npmrcPath}`);
51
+ }
52
+
53
+ // Parse .npmrc
54
+ const config = parseNpmrc(npmrc);
55
+
56
+ // Validate required fields
57
+ if (!config.lp_npm_token_url) {
58
+ throw new Error('Missing lp_npm_token_url in .npmrc');
59
+ }
60
+
61
+ if (!config.lp_auth_token) {
62
+ throw new Error('Missing lp_auth_token in .npmrc');
63
+ }
64
+
65
+ const apiUrl = config.lp_npm_token_url;
66
+ const lpToken = config.lp_auth_token;
67
+
68
+ // Build URL with token as query param
69
+ const url = new URL(apiUrl);
70
+ url.searchParams.set('token', lpToken);
71
+
72
+ // Fetch npm token from API (token in both URL param and header)
73
+ const response = await fetch(url.toString(), {
74
+ headers: {
75
+ 'Authorization': `Bearer ${lpToken}`,
76
+ 'Content-Type': 'application/json'
77
+ }
78
+ });
79
+
80
+ if (!response.ok) {
81
+ if (response.status === 401) {
82
+ throw new Error('Invalid or expired lp_auth_token');
83
+ }
84
+ throw new Error(`API returned status ${response.status}`);
85
+ }
86
+
87
+ const { npmToken } = await response.json();
88
+
89
+ if (!npmToken) {
90
+ throw new Error('No npm token received from API');
91
+ }
92
+
93
+ // Update .npmrc with npm token
94
+ const authLine = `//registry.npmjs.org/:_authToken=${npmToken}`;
95
+
96
+ if (npmrc.includes('registry.npmjs.org')) {
97
+ npmrc = npmrc.replace(
98
+ /\/\/registry\.npmjs\.org\/:_authToken=.*/,
99
+ authLine
100
+ );
101
+ } else {
102
+ npmrc = npmrc.trim() + `\n${authLine}\n`;
103
+ }
104
+
105
+ fs.writeFileSync(npmrcPath, npmrc);
106
+ }
107
+
108
+ module.exports = { configureNpmAuth, parseNpmrc };
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@lawpath-tech/npm-auth",
3
+ "version": "1.0.3",
4
+ "bin": {
5
+ "lawpath-npm-auth": "./bin/cli.js"
6
+ },
7
+ "engines": {
8
+ "node": ">=18.0.0"
9
+ },
10
+ "scripts": {
11
+ "release": "npm version patch --no-git-tag-version && npm publish --access public",
12
+ "release:minor": "npm version minor --no-git-tag-version && npm publish --access public",
13
+ "release:major": "npm version major --no-git-tag-version && npm publish --access public"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public",
17
+ "registry": "https://registry.npmjs.org"
18
+ }
19
+ }