Files
sugoidogo c2c952e96a
/ build (push) Successful in 2m35s
fix types
2025-12-16 01:17:06 -08:00

105 lines
3.1 KiB
TypeScript

import * as TwitchAuth from "./TwitchAuth.ts";
import { AccessTokenMaybeWithUserId, AuthProvider, AccessTokenWithUserId } from "@twurple/auth";
/**
* A type that represents a user and contains a user ID.
*/
interface UserIdResolvableType {
/**
* The ID of the user.
*/
id: string;
}
/**
* A user ID or a user or channel object.
*/
type UserIdResolvable = string | number | UserIdResolvableType;
type Token = TwitchAuth.TwitchToken & AccessTokenMaybeWithUserId
function getTwurpleProxy(token: TwitchAuth.TwitchToken): Token {
return new Proxy(token, {
get(target, name, receiver) {
return target[name.toString().replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)]
}
}) as Token
}
function hasScopes(token: Token, ...scopes: string[]) {
if (!token) {
return false
}
if (!scopes) {
return true
}
for (const scope of scopes) {
if (!token.scope.includes(scope)) {
return false
}
}
return true
}
export default class SugoiAuthProvider implements AuthProvider {
#token: Token
clientId: string;
constructor(client_id: string, proxy_origin = import.meta.url) {
this.clientId = client_id
TwitchAuth.setProxyOrigin(proxy_origin)
}
#setToken = (token: Token) => {
this.#token = token
return token
}
async addUser(...scopes: string[]) {
this.#token = await TwitchAuth.getUserToken(this.clientId, ...scopes).then(getTwurpleProxy).then(this.#setToken)
return this.#token
}
async addUserForToken(token: TwitchAuth.TwitchToken) {
if (token.refresh_token) {
this.#token = await TwitchAuth.refreshToken(this.clientId, token.refresh_token).then(getTwurpleProxy).then(this.#setToken)
return this.#token
}
this.#token = await TwitchAuth.validateToken(token.access_token).then(getTwurpleProxy).then(this.#setToken)
return this.#token
}
removeUser() {
this.#token = null
}
async getAccessTokenForUser(user: UserIdResolvable, ...scopeSets: string[][]) {
if ((!scopeSets[0]) && (this.#token)) {
return this.#token as AccessTokenWithUserId
}
for (const scopes of scopeSets) {
if (hasScopes(this.#token, ...scopes)) {
return this.#token as AccessTokenWithUserId
}
}
this.#token = await TwitchAuth.getUserTokenPassive(this.clientId, ...(scopeSets[0] || [])).then(getTwurpleProxy).then(this.#setToken)
return this.#token as AccessTokenWithUserId
}
async getAnyAccessToken(user: UserIdResolvable) {
return this.#token || TwitchAuth.getAppToken(this.clientId).then(getTwurpleProxy)
}
getCurrentScopesForUser(user: UserIdResolvable) {
if (!this.#token || this.#token instanceof Promise) {
return []
}
return this.#token.scope
}
async refreshAccessTokenForUser(user: UserIdResolvable) {
this.#token = await TwitchAuth.refreshToken(this.clientId, this.#token.refresh_token).then(this.#setToken)
return this.#token as AccessTokenWithUserId
}
}