In Chapter 3: GitHub CLI Integration, we successfully hired a "subcontractor" (the GitHub CLI) to fetch a user's authentication token.
Now we are holding a GitHub OAuth Token in our hands. This is a powerful secret key. If a hacker gets it, they can impersonate the user.
Imagine you are a courier delivering a top-secret message.
In programming, we often print things to the console (console.log) to debug errors.
[REDACTED:gh-token] instead of the actual key.This chapter teaches you how to create a "Sealed Envelope" class that keeps secrets safe until the exact moment they need to be used.
We don't store the token as a simple text string. We wrap it inside a JavaScript Class. This class acts as the envelope.
When you try to turn an object into text (like printing it), JavaScript looks for a method called toString(). We will replace the default behavior with our own version that lies and says "I am redacted."
reveal() Method
We need a specific, deliberate way to open the envelope. We will create a method called .reveal() that returns the actual secret. We only call this when we are absolutely sure we are talking to a secure server.
We are working in api.ts. Let's build the RedactedGithubToken class.
We use a private field (starting with #) to store the value. In TypeScript, private fields cannot be accessed from outside the class.
export class RedactedGithubToken {
// The '#' makes this strictly private
readonly #value: string;
constructor(raw: string) {
this.#value = raw;
}
// ... methods coming next
}
new RedactedGithubToken("gho_SECRET_KEY")#value directly.
Now we define what happens if someone tries to print this object. We override toString() and toJSON().
toString(): string {
return '[REDACTED:gh-token]';
}
toJSON(): string {
return '[REDACTED:gh-token]';
}
console.log("Token is: " + token)."Token is: [REDACTED:gh-token]"
Node.js has a special way of inspecting objects using util.inspect. We need to block that too using a Symbol.
// Special method for Node.js console.log(obj)
[Symbol.for('nodejs.util.inspect.custom')](): string {
return '[REDACTED:gh-token]';
}
console.log(token).[REDACTED:gh-token]Finally, we provide the only way to get the real value.
reveal(): string {
return this.#value;
}
}
token.reveal() returns the raw string "gho_SECRET_KEY".What happens when we pass this token around our app?
.reveal().
Let's look at how this fits into the real api.ts file.
This is the complete class. It is a small but powerful security tool.
// File: api.ts
export class RedactedGithubToken {
readonly #value: string
constructor(raw: string) {
this.#value = raw
}
reveal(): string {
return this.#value
}
toString(): string {
return '[REDACTED:gh-token]'
}
// ... other overrides (toJSON, inspect) ...
}
In Chapter 3: GitHub CLI Integration, you might remember this line in checkLoginState:
// remote-setup.tsx
return {
status: 'has_gh_token',
token: new RedactedGithubToken(trimmed) // <--- Wrapping it here!
};
From this point forward, the token variable is safe to pass around.
In the next chapter, we will see how to use reveal(). We only use it inside the importGithubToken function, right before sending the data to axios (our HTTP client).
// File: api.ts (Preview)
const response = await axios.post(
url,
{ token: token.reveal() }, // <--- Opening the envelope
{ headers }
);
You have learned a vital security practice: Defense in Depth.
RedactedGithubToken class that acts as a Sealed Envelope..reveal().Now that we have the token safely wrapped up, how do we actually send it to our backend server to finish the setup?
Next Chapter: Backend API Client
Generated by Code IQ