@kud/pcloud-auth
v0.1.0
Published
OAuth flow and token storage for pCloud — shared auth layer for CLI, MCP, and extensions
Readme
@kud/pcloud-auth
OAuth flow and token storage for pCloud. Shared auth layer for CLI tools, MCP servers, and browser extensions.
Handles the full credential resolution waterfall: env token → stored tokens → interactive OAuth flow.
Install
npm install @kud/pcloud-authRequires Node ≥ 20. ESM only.
Usage
Quick start with resolveAuth
import { resolveAuth } from "@kud/pcloud-auth"
const api = await resolveAuth()resolveAuth returns a PCloudAPI instance from @kud/pcloud-sdk, ready to use. It tries credentials in this order:
PCLOUD_ACCESS_TOKENenv var- Stored tokens at
~/.config/pcloud/tokens.json - Full OAuth flow using
PCLOUD_CLIENT_ID+PCLOUD_CLIENT_SECRET
If none are available, it throws with a descriptive message.
OAuthFlow
Spins up a local HTTP server, opens the browser to the pCloud authorise page, and exchanges the code for tokens.
import { OAuthFlow } from "@kud/pcloud-auth"
const flow = new OAuthFlow(clientId, clientSecret)
const tokens = await flow.authenticate()
// tokens.access_token, tokens.hostname, tokens.userId, tokens.locationIdConstructor signature:
new OAuthFlow(
clientId: string,
clientSecret: string,
authBaseUrl?: string, // default: "https://my.pcloud.com"
port?: number // default: 3000
)The redirect URI is always http://localhost:<port>/oauth/callback.
TokenStore
Reads and writes tokens to ~/.config/pcloud/tokens.json with 0o600 permissions.
import { TokenStore } from "@kud/pcloud-auth"
const store = new TokenStore()
store.save({ access_token: "…", hostname: "api.pcloud.com" })
const tokens = store.load() // StoredTokens | null
store.exists() // boolean
store.delete()API reference
resolveAuth(options?)
| Option | Type | Default | Description |
| -------------------- | -------- | --------------------------- | ---------------------------------------------- |
| tokenEnvVar | string | "PCLOUD_ACCESS_TOKEN" | Env var name for a raw access token |
| clientIdEnvVar | string | "PCLOUD_CLIENT_ID" | Env var name for the OAuth client ID |
| clientSecretEnvVar | string | "PCLOUD_CLIENT_SECRET" | Env var name for the OAuth client secret |
| defaultApiServer | string | "https://eapi.pcloud.com" | Fallback API server when no hostname is stored |
Returns Promise<PCloudAPI>.
OAuthFlow
| Member | Signature | Description |
| -------------- | ----------------------------------------------- | --------------------------------- |
| constructor | (clientId, clientSecret, authBaseUrl?, port?) | Creates a new flow instance |
| authenticate | () => Promise<OAuthTokens> | Runs the browser-based OAuth flow |
TokenStore
| Method | Signature | Description |
| -------- | -------------------------------- | ---------------------------------------------------------- |
| save | (tokens: StoredTokens) => void | Writes tokens, sets file mode to 0o600 |
| load | () => StoredTokens \| null | Reads stored tokens, returns null on miss or parse error |
| delete | () => void | Removes the token file |
| exists | () => boolean | Returns true if a token file is present |
Types
interface OAuthTokens {
access_token: string
locationId?: number
hostname?: string
userId?: number
}
interface StoredTokens {
access_token: string
hostname?: string
expiresAt?: number
}
interface ResolveAuthOptions {
tokenEnvVar?: string
clientIdEnvVar?: string
clientSecretEnvVar?: string
defaultApiServer?: string
}Environment variables
| Variable | Required | Description |
| ---------------------- | --------- | ---------------------------------------------- |
| PCLOUD_ACCESS_TOKEN | No | Pre-issued access token. Skips OAuth entirely. |
| PCLOUD_CLIENT_ID | For OAuth | OAuth application client ID |
| PCLOUD_CLIENT_SECRET | For OAuth | OAuth application client secret |
At least one of PCLOUD_ACCESS_TOKEN or the PCLOUD_CLIENT_ID + PCLOUD_CLIENT_SECRET pair must be present, unless tokens are already stored on disk.
Licence
MIT
