I have a JAR file (authentication.jar) that is using org.springframework.shell to provide a simple console to generate tokens. In there is defined a custom PromptProvider:
@Component
@RequiredArgsConstructor
public class CustomPromptProvider implements PromptProvider {
private final SessionService sessionService;
@Override
public AttributedString getPrompt() {
String prompt;
if (sessionService.isLogged()) {
prompt = "[" + sessionService.getServerName() + "] " + sessionService.getUsername() + ">";
} else if (sessionService.isConnected()) {
prompt = "[" + sessionService.getServerName() + "]>";
} else {
prompt = "auth-shell>";
}
return new AttributedString(prompt);
}
}
I have created a scenario for expect to start authentication.jar, wait for the prompt to appear, and execute certain commands to automate getting a token. It first waits to see "auth-shell>", connects to the server, waits to see the server name in the prompt, then logs the user.
I made a small bash script that calls the expect scenario with parameters defined in the script, if I ever want to quickly and manually generate a token.
Finally, I created a NodeJS server to allow queries to localhost:3737 to generate tokens: the web server listens for the required info, then runs the expect script, and retrieves the token output that way.
Now, when I run any of the scripts (the JAR file, the expect scenario, the bash script, or the NodeJS server), I get a token without any issue. However, I cannot generate a token when I try to make a LaunchAgent daemon to do it for me.
I am using a MacBook Pro with the M1 chip, and so wish for my NodeJS server to be started at boot. I looked into it, and have made the following file in ~/Library/LaunchAgents:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>node_token_generator</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/node_token_generator.log</string>
<key>StandardErrorPath</key>
<string>/tmp/node_token_generator.log</string>
<key>ProgramArguments</key>
<array>
<string>/bin/sh</string>
<string>-i</string>
<string>-c</string>
<string>/usr/local/bin/node "$HOME/.local/lib/node_token_generator.js"</string>
</array>
</dict>
</plist>
The NodeJS server starts properly, and I can see logs in the log file. However, when I try to generate a token by calling localhost:3737, I get an error. Looking into the log file, I see that instead of printing the expected prompts (e.g. "auth-shell>"), it prints ESC[?2004h>..... Here's an example:
- Logs of authentication.jar when NodeJS server run manually:
auth-shell>connect --server <url> --port <port> Server greetings [Application <app> is running] Connected to [<url>:<port>] [<url>]>activedirectory --username <username> AD password for [<user>] : ************ Your token [<token>] - Logs of authentication.jar when NodeJS server run through LaunchAgent:
ESC[?2004h>....Server greetings [Application <app> is running] Connected to [<url>:<port>] ESC[?2004h>....
I tried on another Macbook Pro, but to no avail. Running the server manually makes the prompt appear properly, and environment variables do not seem to be the issue: running the script manually with only $HOME set still works.
I cloned the authentication.jar repo and put a print in the method that returns the prompt, and I can see that the variable does hold the correct value, but for some reason it is not printed.
Is there any difference in how the LaunchAgent starts the script? sets up its environment? Is there a known bug in the shell provided by Spring?