@metaplay/metaplay-auth 1.1.3 → 1.1.5
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.
- package/CHANGELOG.md +13 -0
- package/dist/auth.js +27 -19
- package/dist/auth.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +10 -12
- package/src/auth.ts +38 -22
- package/src/index.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.5] - 2024-02-26
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
* Switched from express to H3 for a local web server.
|
|
8
|
+
* Introduced native support of node:http for local server creation.
|
|
9
|
+
|
|
10
|
+
## [1.1.4] - 2024-02-23
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
* Fixed URL escaping in the login link.
|
|
15
|
+
|
|
3
16
|
## [1.1.3] - 2024-02-23
|
|
4
17
|
|
|
5
18
|
### Changed
|
package/dist/auth.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
2
|
-
import
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
import { toNodeListener, createApp, defineEventHandler, getQuery, sendError } from 'h3';
|
|
3
4
|
import open from 'open';
|
|
4
5
|
import { randomBytes, createHash } from 'node:crypto';
|
|
5
6
|
import jwt from 'jsonwebtoken';
|
|
6
7
|
import jwkToPem from 'jwk-to-pem';
|
|
7
8
|
import { Configuration, WellknownApi } from '@ory/client';
|
|
8
9
|
import { setSecret, getSecret, removeSecret } from './secret_store.js';
|
|
9
|
-
import { createServer } from 'net';
|
|
10
10
|
import { logger } from './logging.js';
|
|
11
11
|
// oauth2 client details (maybe move these to be discovered from some online location to make changes easier to manage?)
|
|
12
12
|
const clientId = 'c16ea663-ced3-46c6-8f85-38c9681fe1f0';
|
|
@@ -65,29 +65,36 @@ async function findAvailablePort() {
|
|
|
65
65
|
export async function loginAndSaveTokens() {
|
|
66
66
|
// Find an available port to listen on.
|
|
67
67
|
const availablePort = await findAvailablePort();
|
|
68
|
-
const app =
|
|
68
|
+
const app = createApp();
|
|
69
69
|
const redirectUri = `http://localhost:${availablePort}/callback`;
|
|
70
70
|
const { verifier, challenge } = generateCodeVerifierAndChallenge();
|
|
71
71
|
const state = randomBytes(16).toString('hex');
|
|
72
72
|
// Create a /callback endpoint that exchanges the code for tokens.
|
|
73
|
-
app.
|
|
74
|
-
//
|
|
75
|
-
const error =
|
|
76
|
-
|
|
73
|
+
app.use('/callback', defineEventHandler(async (event) => {
|
|
74
|
+
// Read the query parameters.
|
|
75
|
+
const { error, error_description: errorDescription, code } = getQuery(event);
|
|
76
|
+
// Raise an error if the query parameters contain an error message.
|
|
77
77
|
if (error) {
|
|
78
|
-
console.error(`Error logging in. Received the following error:\n\n${error}: ${errorDescription}`);
|
|
79
|
-
|
|
78
|
+
console.error(`Error logging in. Received the following error:\n\n${String(error)}: ${String(errorDescription)}`);
|
|
79
|
+
sendError(event, new Error(`Authentication failed: ${String(error)}: ${String(errorDescription)}`));
|
|
80
80
|
server.close();
|
|
81
81
|
process.exit(1);
|
|
82
82
|
}
|
|
83
|
+
// Raise an error if the query parameters do not contain a code.
|
|
84
|
+
if (typeof code !== 'string') {
|
|
85
|
+
console.error('Error logging in. No code received.');
|
|
86
|
+
sendError(event, new Error('Authentication failed: No code received.'));
|
|
87
|
+
server.close();
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
// Exchange the code for tokens.
|
|
83
91
|
try {
|
|
84
|
-
const code = req.query.code;
|
|
85
92
|
logger.debug(`Received callback request with code ${code}. Preparing to exchange for tokens...`);
|
|
86
93
|
const tokens = await getTokensWithAuthorizationCode(state, redirectUri, verifier, code);
|
|
87
|
-
// TODO: Could return a pre-generated HTML page instead of text?
|
|
88
|
-
res.send('Authentication successful! You can close this window.');
|
|
89
94
|
await saveTokens(tokens);
|
|
90
95
|
console.log('You are now logged in and can call the other commands.');
|
|
96
|
+
// TODO: Could return a pre-generated HTML page instead of text?
|
|
97
|
+
return 'Authentication successful! You can close this window.';
|
|
91
98
|
}
|
|
92
99
|
catch (error) {
|
|
93
100
|
if (error instanceof Error) {
|
|
@@ -98,14 +105,15 @@ export async function loginAndSaveTokens() {
|
|
|
98
105
|
server.close();
|
|
99
106
|
}
|
|
100
107
|
process.exit(0);
|
|
101
|
-
});
|
|
108
|
+
}));
|
|
102
109
|
// Start the server.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
110
|
+
// We use use H3 and adapt it to Node.js's http server.
|
|
111
|
+
const server = createServer(toNodeListener(app)).listen(availablePort);
|
|
112
|
+
logger.debug(`Listening on port ${availablePort} and waiting for callback...`);
|
|
113
|
+
// Open the browser to log in.
|
|
114
|
+
const authorizationUrl = `${authorizationEndpoint}?response_type=code&client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${challenge}&code_challenge_method=S256&scope=${encodeURIComponent('openid offline_access')}&state=${encodeURIComponent(state)}`;
|
|
115
|
+
console.log(`Attempting to open a browser to log in. If a browser did not open up, you can copy-paste the following URL to authenticate:\n\n${authorizationUrl}\n`);
|
|
116
|
+
void open(authorizationUrl);
|
|
109
117
|
}
|
|
110
118
|
/**
|
|
111
119
|
* Refresh access and ID token with a refresh token.
|
package/dist/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,2DAA2D;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ const program = new Command();
|
|
|
8
8
|
program
|
|
9
9
|
.name('metaplay-auth')
|
|
10
10
|
.description('Authenticate with Metaplay and get AWS and Kubernetes credentials for game servers.')
|
|
11
|
-
.version('1.1.
|
|
11
|
+
.version('1.1.5')
|
|
12
12
|
.option('-d, --debug', 'enable debug output')
|
|
13
13
|
.hook('preAction', (thisCommand) => {
|
|
14
14
|
// Handle debug flag for all commands.
|
package/package.json
CHANGED
|
@@ -1,37 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metaplay/metaplay-auth",
|
|
3
3
|
"description": "Utility CLI for authenticating with the Metaplay Auth and making authenticated calls to infrastructure endpoints.",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
7
7
|
"homepage": "https://metaplay.io",
|
|
8
8
|
"bin": "dist/index.js",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "tsx src/index.ts",
|
|
11
|
+
"prepublish": "tsc"
|
|
12
|
+
},
|
|
9
13
|
"publishConfig": {
|
|
10
14
|
"access": "public"
|
|
11
15
|
},
|
|
12
16
|
"devDependencies": {
|
|
17
|
+
"@metaplay/eslint-config": "workspace:*",
|
|
18
|
+
"@metaplay/typescript-config": "workspace:*",
|
|
13
19
|
"@types/express": "^4.17.21",
|
|
14
20
|
"@types/jsonwebtoken": "^9.0.5",
|
|
15
21
|
"@types/jwk-to-pem": "^2.0.3",
|
|
16
22
|
"@types/node": "^20.11.20",
|
|
17
|
-
"typescript": "^5.1.6",
|
|
18
23
|
"tsx": "^4.7.1",
|
|
19
|
-
"
|
|
20
|
-
"@metaplay/typescript-config": "1.0.0"
|
|
24
|
+
"typescript": "^5.1.6"
|
|
21
25
|
},
|
|
22
26
|
"dependencies": {
|
|
23
27
|
"@ory/client": "^1.6.2",
|
|
28
|
+
"commander": "^12.0.0",
|
|
29
|
+
"h3": "^1.10.2",
|
|
24
30
|
"jsonwebtoken": "^9.0.2",
|
|
25
31
|
"jwk-to-pem": "^2.0.5",
|
|
26
|
-
"commander": "^12.0.0",
|
|
27
|
-
"express": "^4.18.2",
|
|
28
|
-
"net": "^1.0.2",
|
|
29
32
|
"open": "^10.0.2",
|
|
30
|
-
"process": "^0.11.10",
|
|
31
33
|
"tslog": "^4.9.2"
|
|
32
|
-
},
|
|
33
|
-
"scripts": {
|
|
34
|
-
"dev": "tsx src/index.ts",
|
|
35
|
-
"prepublish": "tsc"
|
|
36
34
|
}
|
|
37
35
|
}
|
package/src/auth.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import { createServer } from 'node:http'
|
|
4
|
+
import { toNodeListener, createApp, defineEventHandler, getQuery, sendError } from 'h3'
|
|
5
|
+
|
|
3
6
|
import open from 'open'
|
|
4
7
|
import { randomBytes, createHash } from 'node:crypto'
|
|
5
8
|
import jwt from 'jsonwebtoken'
|
|
6
9
|
import jwkToPem from 'jwk-to-pem'
|
|
7
10
|
import { Configuration, WellknownApi } from '@ory/client'
|
|
8
11
|
import { setSecret, getSecret, removeSecret } from './secret_store.js'
|
|
9
|
-
|
|
12
|
+
|
|
10
13
|
import { logger } from './logging.js'
|
|
11
14
|
|
|
12
15
|
// oauth2 client details (maybe move these to be discovered from some online location to make changes easier to manage?)
|
|
@@ -74,35 +77,46 @@ export async function loginAndSaveTokens () {
|
|
|
74
77
|
// Find an available port to listen on.
|
|
75
78
|
const availablePort = await findAvailablePort()
|
|
76
79
|
|
|
77
|
-
const app =
|
|
80
|
+
const app = createApp()
|
|
78
81
|
const redirectUri = `http://localhost:${availablePort}/callback`
|
|
79
82
|
const { verifier, challenge } = generateCodeVerifierAndChallenge()
|
|
80
83
|
const state = randomBytes(16).toString('hex')
|
|
81
84
|
|
|
82
85
|
// Create a /callback endpoint that exchanges the code for tokens.
|
|
83
|
-
app.
|
|
84
|
-
//
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
app.use('/callback', defineEventHandler(async event => {
|
|
87
|
+
// Read the query parameters.
|
|
88
|
+
const {
|
|
89
|
+
error,
|
|
90
|
+
error_description: errorDescription,
|
|
91
|
+
code
|
|
92
|
+
} = getQuery(event)
|
|
93
|
+
|
|
94
|
+
// Raise an error if the query parameters contain an error message.
|
|
88
95
|
if (error) {
|
|
89
|
-
console.error(`Error logging in. Received the following error:\n\n${error}: ${errorDescription}`)
|
|
90
|
-
|
|
96
|
+
console.error(`Error logging in. Received the following error:\n\n${String(error)}: ${String(errorDescription)}`)
|
|
97
|
+
sendError(event, new Error(`Authentication failed: ${String(error)}: ${String(errorDescription)}`))
|
|
98
|
+
server.close()
|
|
99
|
+
process.exit(1)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Raise an error if the query parameters do not contain a code.
|
|
103
|
+
if (typeof code !== 'string') {
|
|
104
|
+
console.error('Error logging in. No code received.')
|
|
105
|
+
sendError(event, new Error('Authentication failed: No code received.'))
|
|
91
106
|
server.close()
|
|
92
107
|
process.exit(1)
|
|
93
108
|
}
|
|
94
109
|
|
|
110
|
+
// Exchange the code for tokens.
|
|
95
111
|
try {
|
|
96
|
-
const code: string | undefined = req.query.code as string
|
|
97
112
|
logger.debug(`Received callback request with code ${code}. Preparing to exchange for tokens...`)
|
|
98
|
-
|
|
99
113
|
const tokens = await getTokensWithAuthorizationCode(state, redirectUri, verifier, code)
|
|
100
|
-
// TODO: Could return a pre-generated HTML page instead of text?
|
|
101
|
-
res.send('Authentication successful! You can close this window.')
|
|
102
|
-
|
|
103
114
|
await saveTokens(tokens)
|
|
104
115
|
|
|
105
116
|
console.log('You are now logged in and can call the other commands.')
|
|
117
|
+
|
|
118
|
+
// TODO: Could return a pre-generated HTML page instead of text?
|
|
119
|
+
return 'Authentication successful! You can close this window.'
|
|
106
120
|
} catch (error) {
|
|
107
121
|
if (error instanceof Error) {
|
|
108
122
|
console.error(`Error: ${error.message}`)
|
|
@@ -112,16 +126,18 @@ export async function loginAndSaveTokens () {
|
|
|
112
126
|
}
|
|
113
127
|
|
|
114
128
|
process.exit(0)
|
|
115
|
-
})
|
|
129
|
+
}))
|
|
116
130
|
|
|
117
131
|
// Start the server.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
console.log(`Attempting to open a browser to log in. If a browser did not open up, you can copy-paste the following URL to authenticate:\n\n${authorizationUrl}\n`)
|
|
121
|
-
void open(authorizationUrl)
|
|
132
|
+
// We use use H3 and adapt it to Node.js's http server.
|
|
133
|
+
const server = createServer(toNodeListener(app)).listen(availablePort)
|
|
122
134
|
|
|
123
|
-
|
|
124
|
-
|
|
135
|
+
logger.debug(`Listening on port ${availablePort} and waiting for callback...`)
|
|
136
|
+
|
|
137
|
+
// Open the browser to log in.
|
|
138
|
+
const authorizationUrl: string = `${authorizationEndpoint}?response_type=code&client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${challenge}&code_challenge_method=S256&scope=${encodeURIComponent('openid offline_access')}&state=${encodeURIComponent(state)}`
|
|
139
|
+
console.log(`Attempting to open a browser to log in. If a browser did not open up, you can copy-paste the following URL to authenticate:\n\n${authorizationUrl}\n`)
|
|
140
|
+
void open(authorizationUrl)
|
|
125
141
|
}
|
|
126
142
|
|
|
127
143
|
/**
|
package/src/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ const program = new Command()
|
|
|
10
10
|
program
|
|
11
11
|
.name('metaplay-auth')
|
|
12
12
|
.description('Authenticate with Metaplay and get AWS and Kubernetes credentials for game servers.')
|
|
13
|
-
.version('1.1.
|
|
13
|
+
.version('1.1.5')
|
|
14
14
|
.option('-d, --debug', 'enable debug output')
|
|
15
15
|
.hook('preAction', (thisCommand) => {
|
|
16
16
|
// Handle debug flag for all commands.
|