[CLIAuth] Python -> Node.JS CLient (CLOSED)

I have Python CLIAuth client wrappers, but I don’t have node.js CLIAuth client wrappers. I’m also kinda not caffeinated enough to translate Python code to pseudo-code to Node.js.

The first person who completes this task and sends an identical copy of the attached code but in Node.JS will receive another 69 cycles (similar to the documentation thing).

After both the docs and the wrappers are completed, I will publish the project.

#!/usr/bin/env python3
"""
A simple yet secure client to the Repl.it Database.

Great for safely sharing one database among many repls, while
preventing abuse to resources which fall under your name.

Copyright @python660, All Rights Reserved.
Licensed under the MIT License, attribution
required for commercial use. Please see LICENSE.md
for more information."""

import asyncio
import time
import shutil
import json
import base64
from colorama import Style, Back, Fore
import os
from websockets.sync.client import connect



def login():
  bright = lambda msg: print(f"{Style.BRIGHT}{msg}{Style.RESET_ALL}")
  normal = lambda msg: print(f"{Style.NORMAL}{msg}{Style.RESET_ALL}")
  dim    = lambda msg: print(f"{Style.DIM}{msg}{Style.RESET_ALL}")
  #red = lambda msg: print(f"{Fore.RED}{msg}{Style.RESET_ALL}")
  bgblue = lambda msg: print(f"{Style.BRIGHT}{Back.BLUE}{msg}{Style.RESET_ALL}")
  red = lambda msg: print(f"{Style.BRIGHT}{Fore.RED}{msg}{Style.RESET_ALL}")
  green = lambda msg: print(f"{Style.BRIGHT}{Fore.GREEN}{msg}{Style.RESET_ALL}")
  yellow = lambda msg: print(f"{Style.DIM}{Fore.WHITE}{msg}{Style.RESET_ALL}")
  if os.environ.get("CLI_AUTH_KEY"):
    print(f"Logged in as {json.loads(json.loads(base64.b64decode(os.environ['CLI_AUTH_KEY']).decode())['payload'])['username']}")
    return json.loads(json.loads(base64.b64decode(os.environ['CLI_AUTH_KEY']).decode())['payload']), base64.b64decode(os.environ["CLI_AUTH_KEY"]).decode()
  with connect("wss://cliauth.repl.co/auth") as websocket:
    msg = websocket.recv()
    #print(f"Received: {msg}")
    #websocket.send("Hello world!")
    #print("Send message")
    #time.sleep(10)
    assert msg.split(":")[0] == "auth_challenge"
    timespan, url = msg.split(":")[1], ":".join(msg.split(":")[2:])
    termsize = shutil.get_terminal_size((80, 80))
    #print(termsize[0])
    bgblue("\n" + " " * (termsize[0]//2-7) + "Authentication" + " " * (termsize[0]//2-7))
    dim("-" * termsize[0])
    bright(f"Please visit the following link in the next {timespan} minute(s) to authenticate:")
    yellow(f"{url}")
    
    msg = websocket.recv()
    assert msg.split(":")[0] == "auth_resolve"
    #print(token)
    status = ":".join(msg.split(":")[1:])
    if status == "success":
      green("Authentication successful.")
    else:
      red("Authentication timed out.")
      raise Exception("Authentication timed out.")

    msg = websocket.recv()
    bright(f"Logged in as {json.loads(json.loads(base64.b64decode( base64.b64encode(msg.encode()).decode() ).decode())['payload'])['username']}")
    bright("To prevent future re-authentication prompts, place the following token into a secret (environment variable) named \"CLI_AUTH_KEY\":")
    yellow(base64.b64encode(msg.encode()).decode())
    bright(f"Treat this token as your password. Do not expose it in your code. You can revoke this token at any time by visiting the following url:")
    yellow("https://cliauth.repl.co/revoke")
    dim("-" * termsize[0])
    bgblue(" " * (termsize[0]//2-11) + "CLI-AUTH by @python660" + " " * (termsize[0]//2-11))
    return json.loads(json.loads(base64.b64decode(base64.b64encode(msg.encode()).decode()).decode())["payload"]), msg

EDIT: TYSM @Matt!

1 Like

However, if AI finishes before you, I will close this topic.

I invited you to a private Repl, I’ve got the login functionality mostly working and then I’m gonna also fix up the colouring. :smile:

1 Like

That last message is never sent, it seems (I tested in your original Python version and get an error due to the connection being unexpectedly closed), so I can’t test the decoding of that last message, but apart from that I’ve fully completed the Node.js port.

hmm… I think that was me experimenting… I dont think that is supposed to happen tho:

authSessions[req.query.otp].ws.send(
  JSON.stringify({
    signature: signature, 
    payload: payload
  })
);
authSessions[req.query.otp].ws.close();

Perhaps it was the premature closing of the websockets? I’ll try to fix it.

EDIT: I am able to read the last message after modifying the ws.close() to happen 5 seconds later, I wonder if thats the problem.

1 Like

The sending is likely asynchronous and it won’t be sent immediately, so if you start closing the socket, it will likely cause the message to not be completely sent, which is pretty much what you guessed.

1 Like