-
Notifications
You must be signed in to change notification settings - Fork 3
chore: migrate-old-mock-api #431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "presets": [["@nx/js/babel", { "useBuiltIns": "entry" }]] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| { | ||
| "extends": ["../../.eslintrc.json"], | ||
| "ignorePatterns": ["!**/*"], | ||
| "overrides": [ | ||
| { | ||
| "ignorePatterns": [ | ||
| "node_modules", | ||
| "*.md", | ||
| "LICENSE", | ||
| ".babelrc", | ||
| ".env*", | ||
| ".bin", | ||
| "dist", | ||
| ".eslintignore" | ||
| ] | ||
| }, | ||
| { | ||
| "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], | ||
| "rules": {} | ||
| }, | ||
| { | ||
| "files": ["*.ts", "*.tsx"], | ||
| "rules": {} | ||
| }, | ||
| { | ||
| "files": ["*.js", "*.jsx"], | ||
| "rules": {} | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "name": "am-mock-api", | ||
| "version": "0.0.0", | ||
| "private": true, | ||
| "description": "", | ||
| "keywords": [], | ||
| "license": "ISC", | ||
| "author": "", | ||
| "main": "./index.js", | ||
| "dependencies": { | ||
| "@types/express": "^4.17.17", | ||
| "body-parser": "^2.2.0", | ||
| "cookie-parser": "^1.4.7", | ||
| "cors": "^2.8.5", | ||
| "express": "^4.21.2", | ||
| "superagent": "^10.2.3", | ||
| "uuid": "^13.0.0" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| { | ||
| "name": "am-mock-api", | ||
| "$schema": "../../node_modules/nx/schemas/project-schema.json", | ||
| "sourceRoot": "e2e/am-mock-api/src", | ||
| "projectType": "application", | ||
| "tags": ["scope:e2e"], | ||
| "targets": { | ||
| "build": { | ||
| "executor": "@nx/js:tsc", | ||
| "outputs": ["{projectRoot}/dist"], | ||
| "options": { | ||
| "outputPath": "e2e/am-mock-api/dist", | ||
| "main": "e2e/am-mock-api/src/index.js", | ||
| "clean": true, | ||
| "tsConfig": "e2e/am-mock-api/tsconfig.app.json", | ||
| "assets": ["e2e/am-mock-api/src/assets"] | ||
| }, | ||
| "configurations": { | ||
| "development": { | ||
| "watch": true | ||
| }, | ||
| "production": { | ||
| "optimization": true, | ||
| "extractLicenses": true, | ||
| "inspect": false, | ||
| "fileReplacements": [ | ||
| { | ||
| "replace": "e2e/am-mock-api/src/environments/environment.ts", | ||
| "with": "e2e/am-mock-api/src/environments/environment.prod.ts" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| }, | ||
| "serve": { | ||
| "executor": "@nx/js:node", | ||
| "outputs": ["{projectRoot}/dist"], | ||
| "options": { | ||
| "buildTarget": "am-mock-api:build" | ||
| } | ||
| }, | ||
| "lint": { | ||
| "options": { | ||
| "fix": true, | ||
| "ignore-path": ".eslintignore", | ||
| "args": ["**/*.ts"] | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,36 @@ | ||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||
| * @forgerock/javascript-sdk | ||||||||||||||||||||||||
| * | ||||||||||||||||||||||||
| * app.auth.js | ||||||||||||||||||||||||
| * | ||||||||||||||||||||||||
| * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. | ||||||||||||||||||||||||
| * This software may be modified and distributed under the terms | ||||||||||||||||||||||||
| * of the MIT license. See the LICENSE file for details. | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import request from 'superagent'; | ||||||||||||||||||||||||
| import { AM_URL, REALM_PATH } from './env.config.js'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export let session; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export async function authorizeApp({ un, pw }) { | ||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||
| const response = await request | ||||||||||||||||||||||||
| .post(`${AM_URL}/json/realms/${REALM_PATH}/authenticate`) | ||||||||||||||||||||||||
| .set('Content-Type', 'application/json') | ||||||||||||||||||||||||
| .set('Accept-API-Version', 'resource=2.0, protocol=1.0') | ||||||||||||||||||||||||
| .set('X-OpenAM-Username', un) | ||||||||||||||||||||||||
| .set('X-OpenAM-Password', pw) | ||||||||||||||||||||||||
| .send({}); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| session = response.body; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| console.log(`REST app identity token: ${session.tokenId}`); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return session; | ||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||
| console.warn('\n###################################################'); | ||||||||||||||||||||||||
| console.warn('WARNING: REST app user for Step Up/Txn Auth missing'); | ||||||||||||||||||||||||
| console.warn('###################################################\n'); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+31
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Propagate authentication failures to caller. The catch block only logs a warning without throwing or returning an error indicator. Callers cannot determine whether authentication succeeded or failed, potentially leading to undefined behavior when accessing the session. Apply this diff to signal failure: } catch (error) {
console.warn('\n###################################################');
console.warn('WARNING: REST app user for Step Up/Txn Auth missing');
console.warn('###################################################\n');
+ throw error; // or return null/undefined to signal failure
}
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| /* | ||
| * @forgerock/javascript-sdk | ||
| * | ||
| * constants.js | ||
| * | ||
| * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. | ||
| * This software may be modified and distributed under the terms | ||
| * of the MIT license. See the LICENSE file for details. | ||
| */ | ||
|
|
||
| export const authPaths = { | ||
| tokenExchange: [ | ||
| '/am/auth/tokenExchange', | ||
| '/am/oauth2/realms/root/access_token', | ||
| '/am/oauth2/realms/root/realms/middleware/access_token', | ||
| '/am/oauth2/realms/root/realms/middleware-modern/access_token', | ||
| '/am/oauth2/realms/root/realms/tokens-expiring-soon/access_token', | ||
| '/am/oauth2/realms/root/realms/tokens-expired/access_token', | ||
| ], | ||
| authenticate: [ | ||
| '/am/auth/authenticate', | ||
| '/am/json/realms/root/authenticate', | ||
| '/am/json/realms/root/realms/middleware/authenticate', | ||
| '/am/json/realms/root/realms/tokens-expiring-soon/authenticate', | ||
| '/am/json/realms/root/realms/tokens-expired/authenticate', | ||
| ], | ||
| htmlAuthenticate: ['/am/'], | ||
| authorize: [ | ||
| '/am/auth/authorize', | ||
| '/am/oauth2/realms/root/authorize', | ||
| '/am/oauth2/realms/root/realms/middleware/authorize', | ||
| '/am/oauth2/realms/root/realms/middleware-modern/authorize', | ||
| '/am/oauth2/realms/root/realms/tokens-expiring-soon/authorize', | ||
| '/am/oauth2/realms/root/realms/tokens-expired/authorize', | ||
| ], | ||
| endSession: [ | ||
| '/am/auth/endSession', | ||
| '/am/oauth2/realms/root/connect/endSession', | ||
| '/am/oauth2/realms/root/connect/idpEndSession', | ||
| '/am/oauth2/realms/root/realms/middleware/connect/endSession', | ||
| '/am/oauth2/realms/root/realms/tokens-expiring-soon/connect/endSession', | ||
| '/am/oauth2/realms/root/realms/tokens-expired/connect/endSession', | ||
| ], | ||
| userInfo: [ | ||
| '/am/auth/userInfo', | ||
| '/am/oauth2/realms/root/userinfo', | ||
| '/am/oauth2/realms/root/realms/middleware/userinfo', | ||
| '/am/oauth2/realms/root/realms/tokens-expiring-soon/userinfo', | ||
| '/am/oauth2/realms/root/realms/tokens-expired/userinfo', | ||
| ], | ||
| revoke: [ | ||
| '/am/auth/revoke', | ||
| '/am/oauth2/realms/root/token/revoke', | ||
| '/am/oauth2/realms/root/realms/middleware/token/revoke', | ||
| '/am/oauth2/realms/root/realms/tokens-expiring-soon/token/revoke', | ||
| '/am/oauth2/realms/root/realms/tokens-expired/token/revoke', | ||
| ], | ||
| sessions: [ | ||
| '/am/auth/sessions', | ||
| '/am/json/realms/root/sessions', | ||
| '/am/json/realms/root/realms/middleware/sessions', | ||
| '/am/json/realms/root/realms/tokens-expiring-soon/sessions', | ||
| '/am/json/realms/root/realms/tokens-expired/sessions', | ||
| ], | ||
| accounts: ['/o/oauth2/v2/auth', '/SAMLFailure', '/SAMLTest'], | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| /* | ||
| * @forgerock/javascript-sdk | ||
| * | ||
| * env.config.js | ||
| * | ||
| * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. | ||
| * This software may be modified and distributed under the terms | ||
| * of the MIT license. See the LICENSE file for details. | ||
| */ | ||
|
|
||
| import { env } from 'process'; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainESM vs. CommonJS: configure modules so Biome and Node agree. Biome parse errors suggest these files are treated as scripts. Either mark this package as ESM or switch to Add a +// e2e/am-mock-api/package.json
+{
+ "name": "am-mock-api",
+ "private": true,
+ "type": "module"
+}Alternatively, rename files to Also applies to: 60-71 🏁 Script executed: #!/bin/bash
# Confirm Biome is parsing these files as scripts (look for the errors)
rg -n "Illegal use of an import declaration outside of a module" -g "!.git"Length of output: 0 I need to gather more information about the actual state of the codebase to verify if the Biome errors mentioned in the review actually exist. 🏁 Script executed: #!/bin/bash
# Check if e2e/am-mock-api/package.json exists
if [ -f "e2e/am-mock-api/package.json" ]; then
echo "=== e2e/am-mock-api/package.json EXISTS ==="
cat "e2e/am-mock-api/package.json"
else
echo "=== e2e/am-mock-api/package.json DOES NOT EXIST ==="
fi
echo ""
echo "=== Directory structure of e2e/am-mock-api ==="
find "e2e/am-mock-api" -type f -name "*.json" -o -name "*.js" -o -name "*.mjs" | head -20
echo ""
echo "=== Content of env.config.js ==="
if [ -f "e2e/am-mock-api/src/app/env.config.js" ]; then
cat "e2e/am-mock-api/src/app/env.config.js"
else
echo "File not found"
fi
echo ""
echo "=== Check for Biome config ==="
if [ -f "biome.json" ] || [ -f "biome.jsonc" ]; then
echo "Found Biome config"
[ -f "biome.json" ] && cat "biome.json" || cat "biome.jsonc"
else
echo "No Biome config found at root"
fiLength of output: 4594 Fix module type mismatch: ESM syntax requires The package.json specifies Note: The referenced Biome parse errors do not appear to be reported—the actual issue is the configuration mismatch. Update {
"name": "am-mock-api",
"version": "0.0.0",
"private": true,
"description": "",
"keywords": [],
"license": "ISC",
"author": "",
- "type": "commonjs",
+ "type": "module",
"main": "./index.js",
...
}Alternatively, convert all files to CommonJS syntax (
🧰 Tools🪛 Biome (2.1.2)[error] 10-11: Illegal use of an import declaration outside of a module not allowed inside scripts (parse) 🤖 Prompt for AI Agents |
||
|
|
||
| /** | ||
| * Configure your environment defaults below. | ||
| */ | ||
| const oauth = { | ||
| client: 'WebOAuthClient', | ||
| scope: 'openid profile me.read', | ||
| }; | ||
| const origins = { | ||
| // Ensure all domains are added to the security cert creation | ||
| app: process.env.NODE_ENV === 'LIVE' ? 'https://sdkapp.petrov.ca' : 'http://localhost', | ||
| forgeops: 'https://default.forgeops.petrov.ca', | ||
| mock: 'http://localhost', | ||
| resource: 'http://localhost', | ||
| }; | ||
|
Comment on lines
+21
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unify LIVE detection and avoid mixed env checks. You use three forms: Apply this diff: @@
-const origins = {
- // Ensure all domains are added to the security cert creation
- app: process.env.NODE_ENV === 'LIVE' ? 'https://sdkapp.petrov.ca' : 'http://localhost',
+const isLive = String(env.LIVE || env.NODE_ENV).toLowerCase() === 'live';
+const origins = {
+ // Ensure all domains are added to the security cert creation
+ app: isLive ? 'https://sdkapp.petrov.ca' : 'http://localhost',
forgeops: 'https://default.forgeops.petrov.ca',
mock: 'http://localhost',
resource: 'http://localhost',
};
@@
-let amUrl;
-let amPort;
+let amUrl;
+let amPort;
@@
-if (env.LIVE) {
+if (isLive) {
amUrl = origins.forgeops;
amPort = ports.forgeops;
} else {
amUrl = origins.mock;
amPort = ports.mock;
}
@@
export const FORGEOPS = origins.forgeops;
+export const FORGEOPS_HOST = new URL(FORGEOPS).hostname;
export const REALM_PATH = realm;Also applies to: 52-58, 64-71 |
||
| const paths = { | ||
| am: '/am', | ||
| }; | ||
| const ports = { | ||
| app: '8443', | ||
| forgeops: '443', | ||
| mock: '9443', | ||
| resource: '9443', | ||
| }; | ||
| const realm = 'root'; | ||
| const testUsers = [ | ||
| { | ||
| // Already exists in forgeops... | ||
| pw: 'password', | ||
| un: 'sdkuser', | ||
| }, | ||
| ]; | ||
|
|
||
| /** | ||
| * The below will be composed of the above values. | ||
| * Do not edit unless you know what you're doing. | ||
| */ | ||
| let amUrl; | ||
| let amPort; | ||
|
|
||
| if (env.LIVE) { | ||
| amUrl = origins.forgeops; | ||
| amPort = ports.forgeops; | ||
| } else { | ||
| amUrl = origins.mock; | ||
| amPort = ports.mock; | ||
| } | ||
|
|
||
| export const APP_PORT = ports.app; | ||
| export const AM_PORT = amPort; | ||
| export const MOCK_PORT = process.env.PORT || ports.mock; | ||
|
|
||
| export const AM_URL = `${amUrl}:${amPort}${paths.am}`; | ||
| export const BASE_URL = `${origins.app}:${ports.app}`; | ||
| export const CLIENT_ID = oauth.client; | ||
| export const FORGEOPS = origins.forgeops; | ||
| export const REALM_PATH = realm; | ||
| export const RESOURCE_URL = `${origins.resource}:${ports.resource}`; | ||
| export const SCOPE = oauth.scope; | ||
| export const USERS = testUsers; | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid mutable module-level state.
Exporting a mutable
sessionvariable that gets modified inauthorizeAppcan lead to race conditions if multiple authorization attempts occur, and makes the module harder to test. Consider returning the session from the function and letting the caller manage state.Refactor to avoid shared mutable state:
Then update callers to store the returned session locally.
🧰 Tools
🪛 Biome (2.1.2)
[error] 13-14: Illegal use of an export declaration outside of a module
not allowed inside scripts
(parse)
🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is this exported session used that moving into the module won't break it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Length of output: 7601
@ryanbas21, the exported
sessionvariable is imported and used ine2e/am-mock-api/src/app/routes.resource.jsat line 13:It's then accessed in three places within that file to set authentication headers when making requests to the AM service:
authorizationmiddleware:.set('iPlanetDirectoryPro', session.tokenId).set('iPlanetDirectoryPro', session.tokenId).set('iPlanetDirectoryPro', session.tokenId)The current flow works like this:
index.jscallsauthorizeApp()(without awaiting it) whenNODE_ENV === 'LIVE'authorizeApp()sets the module-levelsessionvariableroutes.resource.jsare hit, they accesssession.tokenIdfrom the shared module stateTo refactor this without breaking it, you would need to:
index.jsawaitauthorizeApp()and store the resultresourceRoutes(app, session)(and potentiallyauthRoutesif needed)routes.resource.jsto accept a session parameter:export default function (app, session) { ... }sessionfromapp.auth.jsinroutes.resource.jsWould you like me to provide a concrete refactoring example?