@metaplay/metaplay-auth 1.8.0 → 1.9.0

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/eslint.config.js CHANGED
@@ -1,3 +1,12 @@
1
1
  import MetaplayEslintConfig from '@metaplay/eslint-config'
2
2
 
3
- export default MetaplayEslintConfig
3
+ export default [
4
+ ...MetaplayEslintConfig,
5
+ {
6
+ rules: {
7
+ 'no-console': 'off', // CLI tools need to output stuff.
8
+ complexity: 'off', // YOLO
9
+ '@typescript-eslint/no-unsafe-type-assertion': 'off', // This project is going away, not fixing
10
+ }
11
+ }
12
+ ]
package/index.ts CHANGED
@@ -86,7 +86,6 @@ interface PortalEnvironmentInfo {
86
86
  * @param environment Environment slug.
87
87
  * @returns The portal's information about the environment.
88
88
  */
89
-
90
89
  async function fetchManagedEnvironmentInfoWithSlugs(
91
90
  tokens: TokenSet,
92
91
  organization: string,
@@ -107,6 +106,7 @@ async function fetchManagedEnvironmentInfoWithSlugs(
107
106
  await checkEnvironmentInfoResponseError(response)
108
107
 
109
108
  // \todo Validate response?
109
+
110
110
  const portalEnvInfo = (await response.json()) as PortalEnvironmentInfo
111
111
  logger.debug(`Portal returned environment info: ${JSON.stringify(portalEnvInfo, undefined, 2)}`)
112
112
  return portalEnvInfo
@@ -206,17 +206,18 @@ async function resolveTargetEnvironment(
206
206
  // Address is one of:
207
207
  // - FQDN of the target environment, eg, 'idler-develop.p1.metaplay.io'
208
208
  // - Tuple of '<organization>-<project>-<environment>' slugs (eg, 'metaplay-idler-develop')
209
- // - Stable humanId, eg, 'delicious-elephant'
209
+ // - Stable human ID (2 or 4 segments), eg, 'delicious-elephant' or 'fancy-delicious-bear-jumps'
210
210
  if (isValidFQDN(address)) {
211
211
  console.warn('Using the FQDN to specify target environment is deprecated. Use the "<organization>-<project>-<environment>" slugs instead.')
212
212
  return resolveTargetEnvironmentFromFQDN(tokens, address)
213
213
  } else {
214
214
  const parts = address.split('-')
215
- if (parts.length === 2) {
216
- // Two parts is humanId, eg, 'delicious-elephant'
215
+ if (parts.length === 2 || parts.length === 4) {
216
+ // Two segments is old-style environment human ID, eg, 'delicious-elephant'.
217
+ // Four segments is new-style project-suffixed human ID, eg, 'fancy-delicious-bear-jumps'.
217
218
  return await resolveTargetEnvironmentHumanId(tokens, address)
218
219
  } else if (parts.length === 3) {
219
- // Three parts is tuple of slush '<organization>-<project>-<environment>'
220
+ // Three parts is tuple of slugs '<organization>-<project>-<environment>'
220
221
  return await resolveTargetEnvironmentFromSlugs(tokens, parts[0], parts[1], parts[2])
221
222
  } else {
222
223
  throw new Error(`Invalid environment address syntax '${address}'. Specify either the environment's id (eg, "delicious-elephant") or its slug tripled (eg, "<organization>-<project>-<environment>")`)
@@ -609,7 +610,7 @@ program
609
610
  .argument('image-tag', 'docker image tag to deploy (usually the SHA of the build)')
610
611
  .requiredOption('-f, --values <path-to-values-file>', 'path to Helm values file to use for this deployment')
611
612
  .option('--local-chart-path <path-to-chart-directory>', 'path to local Helm chart directory (to use a chart from local disk)')
612
- .option('--helm-chart-repo <url>', 'override the URL of the Helm chart repository (eg, https://charts.metaplay.dev/testing)')
613
+ .option('--helm-chart-repo <url>', 'override the URL of the Helm chart repository (eg, https://customchartrepo.domain.com)')
613
614
  .option('--helm-chart-version <version>', 'the Helm chart version to use (eg, 0.6.0)')
614
615
  .option('--deployment-name', 'Helm deployment name to use', 'gameserver')
615
616
  .hook('preAction', async () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
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.8.0",
4
+ "version": "1.9.0",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
7
7
  "homepage": "https://metaplay.io",
@@ -20,25 +20,25 @@
20
20
  "@types/dockerode": "3.3.32",
21
21
  "@types/express": "5.0.0",
22
22
  "@types/js-yaml": "4.0.9",
23
- "@types/jsonwebtoken": "9.0.7",
23
+ "@types/jsonwebtoken": "9.0.8",
24
24
  "@types/jwk-to-pem": "2.0.3",
25
- "@types/node": "22.10.1",
25
+ "@types/node": "22.13.5",
26
26
  "@types/semver": "7.5.8",
27
- "esbuild": "0.24.0",
28
- "tsx": "4.19.2",
27
+ "esbuild": "0.25.0",
28
+ "tsx": "4.19.3",
29
29
  "typescript": "5.6.3",
30
- "vitest": "2.1.8",
31
- "@aws-sdk/client-ecr": "3.699.0",
30
+ "vitest": "3.0.6",
31
+ "@aws-sdk/client-ecr": "3.750.0",
32
32
  "@kubernetes/client-node": "1.0.0-rc7",
33
- "@ory/client": "1.15.13",
33
+ "@ory/client": "1.16.7",
34
34
  "commander": "12.1.0",
35
35
  "dockerode": "4.0.2",
36
- "h3": "1.13.0",
36
+ "h3": "1.15.0",
37
37
  "js-yaml": "4.1.0",
38
38
  "jsonwebtoken": "9.0.2",
39
39
  "jwk-to-pem": "2.0.7",
40
40
  "open": "8.4.2",
41
- "semver": "7.6.3",
41
+ "semver": "7.7.1",
42
42
  "tslog": "4.9.3"
43
43
  }
44
44
  }
package/src/auth.ts CHANGED
@@ -1,4 +1,4 @@
1
-
1
+
2
2
  import { toNodeListener, createApp, defineEventHandler, getQuery, sendError } from 'h3'
3
3
  import jwt from 'jsonwebtoken'
4
4
  import jwkToPem from 'jwk-to-pem'
@@ -131,18 +131,11 @@ export async function loginAndSaveTokens(): Promise<void> {
131
131
 
132
132
  // Raise an error if the query parameters contain an error message.
133
133
  if (error) {
134
- let errorMessage
135
-
136
- if (typeof error === 'object') {
137
- errorMessage = JSON.stringify(error)
138
- } else {
139
- errorMessage = error
140
- }
134
+ const errorMessage = (typeof error === 'object') ? JSON.stringify(error) : String(error)
135
+ const errorDescriptionStr = (typeof errorDescription === 'object') ? JSON.stringify(errorDescription) : String(errorDescription)
141
136
 
142
- console.error(
143
- `Error logging in. Received the following error:\n\n${errorMessage}: ${String(errorDescription)}`
144
- )
145
- sendError(event, new Error(`Authentication failed: ${errorMessage}: ${String(errorDescription)}`))
137
+ console.error(`Error logging in. Received the following error:\n\n${errorMessage}: ${errorDescriptionStr}`)
138
+ sendError(event, new Error(`Authentication failed: ${errorMessage}: ${errorDescriptionStr}`))
146
139
  server.close()
147
140
  process.exit(1)
148
141
  }
@@ -332,7 +325,7 @@ async function extendCurrentSessionWithRefreshToken(
332
325
  * @param code
333
326
  * @returns
334
327
  */
335
-
328
+
336
329
  async function getTokensWithAuthorizationCode(
337
330
  state: string,
338
331
  redirectUri: string,
@@ -399,7 +392,7 @@ export async function saveTokens(tokens: Record<string, string>): Promise<void>
399
392
 
400
393
  logger.debug('Tokens successfully stored.')
401
394
 
402
- await showTokenInfo(tokens.access_token)
395
+ showTokenInfo(tokens.access_token)
403
396
  } catch (error) {
404
397
  if (error instanceof Error) {
405
398
  throw new Error(`Failed to save tokens: ${error.message}`)
@@ -465,7 +458,7 @@ async function validateToken(token: string): Promise<boolean> {
465
458
  * A helper function which shows token info after being fully decoded.
466
459
  * @param token The token to show info for.
467
460
  */
468
- async function showTokenInfo(token: string): Promise<void> {
461
+ function showTokenInfo(token: string): void {
469
462
  logger.debug('Showing access token info...')
470
463
  // Decode the token
471
464
  const completeTokenData = jwt.decode(token, { complete: true })
@@ -1,7 +1,8 @@
1
1
  import { Command } from 'commander'
2
- import { existsSync } from 'fs'
2
+ import { readFileSync, existsSync } from 'fs'
3
3
  import path from 'path'
4
4
  import { exit } from 'process'
5
+ import * as semver from 'semver'
5
6
 
6
7
  import { pathJoin, executeCommand, ExecuteCommandResult } from './utils.js'
7
8
 
@@ -26,6 +27,15 @@ function resolveBuildEngine(engine?: string): string {
26
27
  return engine
27
28
  }
28
29
 
30
+ function extractSdkVersionFromDockerfile(filePath: string): string {
31
+ const content = readFileSync(filePath, 'utf8')
32
+ const match = /LABEL\s+io\.metaplay\.sdk_version\s*=\s*([\d.]+(?:-[\w.]+)?)(?:[\s\\]*)/.exec(content)
33
+ if (!match) {
34
+ throw Error('Unable to parse SDK version from Dockerfile.server')
35
+ }
36
+ return match[1]
37
+ }
38
+
29
39
  export function registerBuildCommand(program: Command): void {
30
40
  program
31
41
  .command('build-image [extraArgs...]')
@@ -98,6 +108,17 @@ export function registerBuildCommand(program: Command): void {
98
108
  exit(2)
99
109
  }
100
110
 
111
+ // Check for Metaplay SDK R32 or above; the new CLI must be used.
112
+ const sdkVersion = extractSdkVersionFromDockerfile(dockerFilePath)
113
+ console.log(`Metaplay SDK version: ${sdkVersion}`)
114
+ if (semver.gte(sdkVersion, '32.0.0')) {
115
+ console.error('ERROR: metaplay-auth is not compatible with Metaplay SDK Release 32 and above.')
116
+ console.error('See the Release 32 migration guide for more details:')
117
+ // \todo Add direct link to migration guide (when available)
118
+ console.error(' https://docs.metaplay.io/miscellaneous/sdk-updates/release-notes/release-32.html#')
119
+ exit(2)
120
+ }
121
+
101
122
  // Check projectRoot directory
102
123
  const projectRootPath = options.projectRoot.replaceAll('\\', '/')
103
124
  if (path.isAbsolute(sdkRootPath)) {
package/src/deployment.ts CHANGED
@@ -254,7 +254,7 @@ function resolvePodGameServerImageTag(pod: V1Pod): string | null {
254
254
  if (!containerSpec.image) {
255
255
  return null
256
256
  }
257
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
257
+
258
258
  const [_, imageTag] = containerSpec.image.split(':')
259
259
  return imageTag
260
260
  }
@@ -89,7 +89,7 @@ export async function removeSecret(key: string): Promise<void> {
89
89
  logger.debug(`Removing secret ${key}...`)
90
90
 
91
91
  const currentSecrets = await loadSecrets()
92
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
92
+
93
93
  const { [key]: _, ...secrets } = currentSecrets // remove key from secrets
94
94
 
95
95
  const secretJson = JSON.stringify(secrets)
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const PACKAGE_VERSION = "1.8.0"
1
+ export const PACKAGE_VERSION = "1.9.0"
Binary file