From 59f15b7e601b2c8b878c283547ec3d06d90a1e5f Mon Sep 17 00:00:00 2001 From: sugoidogo Date: Sat, 25 Oct 2025 07:50:44 -0700 Subject: [PATCH] remove compiler output from git --- .gitignore | 7 ++++++- static/SugoiAuthProvider.js | 2 -- static/SugoiAuthProvider.js.map | 7 ------- static/TwitchAuth.js | 2 -- static/TwitchAuth.js.map | 7 ------- static/WebStorage.js | 3 --- static/WebStorage.js.map | 7 ------- static/tba.js | 2 -- static/tba.js.map | 7 ------- 9 files changed, 6 insertions(+), 38 deletions(-) delete mode 100644 static/SugoiAuthProvider.js delete mode 100644 static/SugoiAuthProvider.js.map delete mode 100644 static/TwitchAuth.js delete mode 100644 static/TwitchAuth.js.map delete mode 100644 static/WebStorage.js delete mode 100644 static/WebStorage.js.map delete mode 100644 static/tba.js delete mode 100644 static/tba.js.map diff --git a/.gitignore b/.gitignore index 07993eb..97d74b6 100644 --- a/.gitignore +++ b/.gitignore @@ -170,4 +170,9 @@ dist worker.capnp docker-compose.yml -Dockerfile \ No newline at end of file +Dockerfile + +# typescript output + +static/*.js +static/*.js.map \ No newline at end of file diff --git a/static/SugoiAuthProvider.js b/static/SugoiAuthProvider.js deleted file mode 100644 index a05a93a..0000000 --- a/static/SugoiAuthProvider.js +++ /dev/null @@ -1,2 +0,0 @@ -var N=Object.create;var q=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty;var E=r=>{throw TypeError(r)};var H=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var J=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of $(e))!G.call(r,i)&&i!==t&&q(r,i,{get:()=>e[i],enumerable:!(n=Z(e,i))||n.enumerable});return r};var K=(r,e,t)=>(t=r!=null?N(B(r)):{},J(e||!r||!r.__esModule?q(t,"default",{value:r,enumerable:!0}):t,r));var W=(r,e,t)=>e.has(r)||E("Cannot "+t);var s=(r,e,t)=>(W(r,e,"read from private field"),t?t.call(r):e.get(r)),x=(r,e,t)=>e.has(r)?E("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),f=(r,e,t,n)=>(W(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t);var z=H((v,U)=>{(function(r,e){typeof v=="object"&&typeof U<"u"?U.exports=e():typeof define=="function"&&define.amd?define(e):(r=typeof globalThis<"u"?globalThis:r||self,r.fetchRetry=e())})(v,function(){"use strict";var r=function(n,i){if(i=i||{},typeof n!="function")throw new t("fetch must be a function");if(typeof i!="object")throw new t("defaults must be an object");if(i.retries!==void 0&&!e(i.retries))throw new t("retries must be a positive integer");if(i.retryDelay!==void 0&&!e(i.retryDelay)&&typeof i.retryDelay!="function")throw new t("retryDelay must be a positive integer or a function returning a positive integer");if(i.retryOn!==void 0&&!Array.isArray(i.retryOn)&&typeof i.retryOn!="function")throw new t("retryOn property expects an array or function");var M={retries:3,retryDelay:1e3,retryOn:[]};return i=Object.assign(M,i),function(A,c){var _=i.retries,l=i.retryDelay,d=i.retryOn;if(c&&c.retries!==void 0)if(e(c.retries))_=c.retries;else throw new t("retries must be a positive integer");if(c&&c.retryDelay!==void 0)if(e(c.retryDelay)||typeof c.retryDelay=="function")l=c.retryDelay;else throw new t("retryDelay must be a positive integer or a function returning a positive integer");if(c&&c.retryOn)if(Array.isArray(c.retryOn)||typeof c.retryOn=="function")d=c.retryOn;else throw new t("retryOn property expects an array or function");return new Promise(function(b,w){var L=function(h){var P=typeof Request<"u"&&A instanceof Request?A.clone():A;n(P,c).then(function(a){if(Array.isArray(d)&&d.indexOf(a.status)===-1)b(a);else if(typeof d=="function")try{return Promise.resolve(d(h,null,a)).then(function(u){u?p(h,null,a):b(a)}).catch(w)}catch(u){w(u)}else h<_?p(h,null,a):b(a)}).catch(function(a){if(typeof d=="function")try{Promise.resolve(d(h,a,null)).then(function(u){u?p(h,a,null):w(a)}).catch(function(u){w(u)})}catch(u){w(u)}else h<_?p(h,a,null):w(a)})};function p(h,P,a){var u=typeof l=="function"?l(h,P,a):l;setTimeout(function(){L(++h)},u)}L(0)})}};function e(n){return Number.isInteger(n)&&n>=0}function t(n){this.name="ArgumentError",this.message=n}return r})});var j=K(z()),k=(0,j.default)(globalThis.fetch,{retries:10,retryDelay:r=>r*1e3}),T=location.origin+location.pathname,O=new URL("/oauth2/token",import.meta.url);function I(r){return r.obtainment_timestamp=Date.now(),r}function C(r){let e=new URLSearchParams({client_id:r,grant_type:"client_credentials"});return k(O,{method:"POST",body:e.toString(),headers:{"content-type":"application/x-www-form-urlencoded"}}).then(async function(t){if(!t.ok)throw new Error(await t.text());let n=await t.json();return I(n)})}function Q(r,...e){console.debug("requesting authorization code");let t=new URL("https://id.twitch.tv/oauth2/authorize");return t.searchParams.append("response_type","code"),t.searchParams.append("client_id",r),t.searchParams.append("scope",e.join(" ").trim()),location.assign(t+"&redirect_uri="+T),new Promise(()=>{})}function V(r,e){console.debug("exchanging authorization code");let t=new URLSearchParams({client_id:r,code:e,grant_type:"authorization_code"});return k(O,{method:"POST",body:t.toString()+"&redirect_uri="+T,headers:{"content-type":"application/x-www-form-urlencoded"}}).then(async function(n){if(!n.ok)throw new Error(await n.text());let i=await n.json();return I(i)})}async function D(r){return console.debug("validating token"),k("https://id.twitch.tv/oauth2/validate",{headers:{authorization:"OAuth "+r}}).then(async e=>{if(!e.ok)throw new Error(await e.text());let t=await e.json();return t.access_token=r,t.scope=t.scopes,delete t.scopes,t.token_type="bearer",I(t)})}function m(r,e){console.debug("refreshing token");let t=new URLSearchParams({client_id:r,grant_type:"refresh_token",refresh_token:e});return k(O,{method:"POST",body:t.toString(),headers:{"content-type":"application/x-www-form-urlencoded"}}).then(async function(n){if(!n.ok)throw new Error(await n.text());return await n.json()})}async function F(r,...e){let t=await R(r,...e);return t||Q(r,...e)}async function R(r,...e){console.debug("scopes requested:",...e);let t=new URLSearchParams(location.search+"&"+location.hash.substring(1));if(t.has("code")){let n=t.get("code");return history.replaceState(null,"",T),V(r,n)}if(t.has("refresh_token"))return m(r,t.get("refresh_token"));if(t.has("access_token"))return D(t.get("access_token"));if(t.has("error")){let n=t.get("error")+": "+t.get("error_description");throw history.replaceState(null,"",T),new Error(n)}return null}function g(r){return new Proxy(r,{get(e,t,n){return e[t.toString().replace(/[A-Z]/g,i=>`_${i.toLowerCase()}`)]}})}function Y(r,...e){if(!r)return!1;if(!e)return!0;for(let t of e)if(!r.scope.includes(t))return!1;return!0}var o,y,S=class{constructor(e){x(this,o);x(this,y,e=>(f(this,o,e),e));this.clientId=e}async addUser(...e){return f(this,o,await F(this.clientId,...e).then(g).then(s(this,y))),s(this,o)}async addUserForToken(e){return e.refresh_token?(f(this,o,await m(this.clientId,e.refresh_token).then(g).then(s(this,y))),s(this,o)):(f(this,o,await D(e.access_token).then(g).then(s(this,y))),s(this,o))}removeUser(){f(this,o,null)}async getAccessTokenForUser(e,...t){if(!t[0]&&s(this,o))return s(this,o);for(let n of t)if(Y(s(this,o),...n))return s(this,o);return f(this,o,await R(this.clientId,...t[0]||[]).then(g).then(s(this,y))),s(this,o)}async getAnyAccessToken(e){return s(this,o)||C(this.clientId).then(g)}getCurrentScopesForUser(e){return!s(this,o)||s(this,o)instanceof Promise?[]:s(this,o).scope}async refreshAccessTokenForUser(e){return f(this,o,await m(this.clientId,s(this,o).refresh_token).then(s(this,y))),s(this,o)}};o=new WeakMap,y=new WeakMap;export{S as default}; -//# sourceMappingURL=SugoiAuthProvider.js.map diff --git a/static/SugoiAuthProvider.js.map b/static/SugoiAuthProvider.js.map deleted file mode 100644 index 26bd03b..0000000 --- a/static/SugoiAuthProvider.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../node_modules/fetch-retry/dist/fetch-retry.umd.js", "../static_src/TwitchAuth.ts", "../static_src/SugoiAuthProvider.ts"], - "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.fetchRetry = factory());\n})(this, (function () { 'use strict';\n\n var fetchRetry = function (fetch, defaults) {\n defaults = defaults || {};\n if (typeof fetch !== 'function') {\n throw new ArgumentError('fetch must be a function');\n }\n\n if (typeof defaults !== 'object') {\n throw new ArgumentError('defaults must be an object');\n }\n\n if (defaults.retries !== undefined && !isPositiveInteger(defaults.retries)) {\n throw new ArgumentError('retries must be a positive integer');\n }\n\n if (defaults.retryDelay !== undefined && !isPositiveInteger(defaults.retryDelay) && typeof defaults.retryDelay !== 'function') {\n throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');\n }\n\n if (defaults.retryOn !== undefined && !Array.isArray(defaults.retryOn) && typeof defaults.retryOn !== 'function') {\n throw new ArgumentError('retryOn property expects an array or function');\n }\n\n var baseDefaults = {\n retries: 3,\n retryDelay: 1000,\n retryOn: [],\n };\n\n defaults = Object.assign(baseDefaults, defaults);\n\n return function fetchRetry(input, init) {\n var retries = defaults.retries;\n var retryDelay = defaults.retryDelay;\n var retryOn = defaults.retryOn;\n\n if (init && init.retries !== undefined) {\n if (isPositiveInteger(init.retries)) {\n retries = init.retries;\n } else {\n throw new ArgumentError('retries must be a positive integer');\n }\n }\n\n if (init && init.retryDelay !== undefined) {\n if (isPositiveInteger(init.retryDelay) || (typeof init.retryDelay === 'function')) {\n retryDelay = init.retryDelay;\n } else {\n throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');\n }\n }\n\n if (init && init.retryOn) {\n if (Array.isArray(init.retryOn) || (typeof init.retryOn === 'function')) {\n retryOn = init.retryOn;\n } else {\n throw new ArgumentError('retryOn property expects an array or function');\n }\n }\n\n // eslint-disable-next-line no-undef\n return new Promise(function (resolve, reject) {\n var wrappedFetch = function (attempt) {\n // As of node 18, this is no longer needed since node comes with native support for fetch:\n /* istanbul ignore next */\n var _input =\n typeof Request !== 'undefined' && input instanceof Request\n ? input.clone()\n : input;\n fetch(_input, init)\n .then(function (response) {\n if (Array.isArray(retryOn) && retryOn.indexOf(response.status) === -1) {\n resolve(response);\n } else if (typeof retryOn === 'function') {\n try {\n // eslint-disable-next-line no-undef\n return Promise.resolve(retryOn(attempt, null, response))\n .then(function (retryOnResponse) {\n if(retryOnResponse) {\n retry(attempt, null, response);\n } else {\n resolve(response);\n }\n }).catch(reject);\n } catch (error) {\n reject(error);\n }\n } else {\n if (attempt < retries) {\n retry(attempt, null, response);\n } else {\n resolve(response);\n }\n }\n })\n .catch(function (error) {\n if (typeof retryOn === 'function') {\n try {\n // eslint-disable-next-line no-undef\n Promise.resolve(retryOn(attempt, error, null))\n .then(function (retryOnResponse) {\n if(retryOnResponse) {\n retry(attempt, error, null);\n } else {\n reject(error);\n }\n })\n .catch(function(error) {\n reject(error);\n });\n } catch(error) {\n reject(error);\n }\n } else if (attempt < retries) {\n retry(attempt, error, null);\n } else {\n reject(error);\n }\n });\n };\n\n function retry(attempt, error, response) {\n var delay = (typeof retryDelay === 'function') ?\n retryDelay(attempt, error, response) : retryDelay;\n setTimeout(function () {\n wrappedFetch(++attempt);\n }, delay);\n }\n\n wrappedFetch(0);\n });\n };\n };\n\n function isPositiveInteger(value) {\n return Number.isInteger(value) && value >= 0;\n }\n\n function ArgumentError(message) {\n this.name = 'ArgumentError';\n this.message = message;\n }\n\n return fetchRetry;\n\n}));\n", "import fetch_retry from 'fetch-retry'\nconst fetch = fetch_retry(globalThis.fetch, {\n retries: 10,\n retryDelay: attempts => attempts * 1000\n})\n\nexport interface TwitchToken {\n access_token: string\n expires_in: number\n obtainment_timestamp: number\n token_type: string\n user_id?: number\n scope?: Array\n refresh_token?: string\n login?: string\n client_id?: string\n}\n\nexport interface AuthCode {\n code: string\n scope: string\n}\n\nconst redirect_uri = location.origin + location.pathname\nconst proxy_uri = new URL('/oauth2/token', import.meta.url)\n\n/**\n * Timestamp and return the token\n * @param {TwitchToken} token \n * @returns {TwitchToken}\n */\nfunction stamp(token: TwitchToken): TwitchToken {\n token.obtainment_timestamp = Date.now()\n return token\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#client-credentials-grant-flow\n * @param {string} client_id \n * @returns {Promise}\n */\nexport function getAppToken(client_id: string): Promise {\n const searchParams = new URLSearchParams({\n client_id: client_id,\n grant_type: 'client_credentials'\n })\n return fetch(proxy_uri, {\n method: 'POST',\n body: searchParams.toString(),\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\n }).then(async function (response) {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n const token = await response.json()\n return stamp(token)\n })\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#implicit-grant-flow\n * @param {string} client_id \n * @param {Array|string} scopes \n * @returns {Promise}\n */\nexport function requestAccessToken(client_id: string, ...scopes: Array) {\n console.debug('requesting access token')\n const url = new URL('https://id.twitch.tv/oauth2/authorize')\n url.searchParams.append('response_type', 'token')\n url.searchParams.append('client_id', client_id)\n url.searchParams.append('scope', scopes.join(' '))\n location.assign(url + '&redirect_uri=' + redirect_uri)\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#get-the-user-to-authorize-your-app\n * @param {string} client_id \n * @param {Array|string} scopes \n * @returns {Promise}\n */\nexport function requestAuthCode(client_id: string, ...scopes: Array): Promise {\n console.debug('requesting authorization code')\n const url = new URL('https://id.twitch.tv/oauth2/authorize')\n url.searchParams.append('response_type', 'code')\n url.searchParams.append('client_id', client_id)\n url.searchParams.append('scope', scopes.join(' ').trim())\n location.assign(url + '&redirect_uri=' + redirect_uri)\n return new Promise(()=>{})\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#use-the-authorization-code-to-get-a-token\n * @param {string} client_id \n * @param {string} code \n * @returns {Promise}\n */\nexport function exchangeCode(client_id: string, code: string): Promise {\n console.debug('exchanging authorization code')\n const searchParams = new URLSearchParams({\n client_id: client_id,\n code: code,\n grant_type: 'authorization_code'\n })\n return fetch(proxy_uri, {\n method: 'POST',\n body: searchParams.toString() + '&redirect_uri=' + redirect_uri,\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\n }).then(async function (response) {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n const token = await response.json()\n return stamp(token)\n })\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/validate-tokens/#how-to-validate-a-token\n * @param {string} access_token \n * @returns {TwitchToken}\n */\nexport async function validateToken(access_token: string): Promise {\n console.debug('validating token')\n return fetch('https://id.twitch.tv/oauth2/validate', {\n headers: { authorization: 'OAuth ' + access_token }\n }).then(async response => {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n /** @type {TwitchToken} */\n const token: any = await response.json()\n token.access_token = access_token\n token.scope = token.scopes\n delete token.scopes\n token.token_type = 'bearer'\n return stamp(token)\n })\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/refresh-tokens/#how-to-use-a-refresh-token\n * @param {string} client_id \n * @param {string} refresh_token \n * @returns {Promise}\n */\nexport function refreshToken(client_id: string, refresh_token: string): Promise {\n console.debug('refreshing token')\n const searchParams = new URLSearchParams({\n client_id: client_id,\n grant_type: 'refresh_token',\n refresh_token: refresh_token\n })\n return fetch(proxy_uri, {\n method: 'POST',\n body: searchParams.toString(),\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\n }).then(async function (response) {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n return await response.json()\n })\n}\n\n/**\n * This function checks the url search parameters and hash for an auth code,\n * refresh token, access token, or error message, in that order,\n * and if it finds none of those, starts the auth code grant flow.\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#authorization-code-grant-flow\n * @param {string} client_id \n * @returns {TwitchToken}\n */\nexport async function getUserToken(client_id: string, ...scopes): Promise {\n const token=await getUserTokenPassive(client_id, ...scopes)\n if(!token){\n return requestAuthCode(client_id, ...scopes)\n }\n return token\n}\n\n/**\n * This function checks the url search parameters and hash for an auth code,\n * refresh token, access token, or error message, in that order.\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#authorization-code-grant-flow\n * @param {string} client_id \n * @returns {TwitchToken}\n */\nexport async function getUserTokenPassive(client_id: string, ...scopes): Promise{\n console.debug('scopes requested:',...scopes)\n const params = new URLSearchParams(location.search + '&' + location.hash.substring(1))\n if (params.has('code')) {\n const code = params.get('code')\n history.replaceState(null, '', redirect_uri)\n return exchangeCode(client_id, code)\n }\n if (params.has('refresh_token')) {\n return refreshToken(client_id, params.get('refresh_token'))\n }\n if (params.has('access_token')) {\n return validateToken(params.get('access_token'))\n }\n if (params.has('error')) {\n const error_message = params.get('error') + ': ' + params.get('error_description')\n history.replaceState(null, '', redirect_uri)\n throw new Error(error_message)\n }\n return null\n}\n\nexport default getUserToken", "import * as TwitchAuth from \"./TwitchAuth.ts\";\nimport { AccessTokenMaybeWithUserId, AuthProvider, AccessToken, AccessTokenWithUserId } from \"@twurple/auth\";\n\ntype Token = TwitchAuth.TwitchToken & AccessTokenMaybeWithUserId\n\nfunction getTwurpleProxy(token: TwitchAuth.TwitchToken): Token {\n return new Proxy(token, {\n get(target, name, receiver) {\n return target[name.toString().replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)]\n }\n }) as Token\n}\n\nfunction hasScopes(token: Token, ...scopes: string[]) {\n if (!token) {\n return false\n }\n if (!scopes) {\n return true\n }\n for (const scope of scopes) {\n if (!token.scope.includes(scope)) {\n return false\n }\n }\n return true\n}\n\nexport default class SugoiAuthProvider implements AuthProvider {\n\n #token: Token\n clientId: string;\n\n constructor(client_id: string) {\n this.clientId = client_id\n }\n\n #setToken = (token: Token) => {\n this.#token = token\n return token\n }\n\n async addUser(...scopes: string[]) {\n this.#token = await TwitchAuth.getUserToken(this.clientId, ...scopes).then(getTwurpleProxy).then(this.#setToken)\n return this.#token\n }\n\n async addUserForToken(token: TwitchAuth.TwitchToken) {\n if (token.refresh_token) {\n this.#token = await TwitchAuth.refreshToken(this.clientId, token.refresh_token).then(getTwurpleProxy).then(this.#setToken)\n return this.#token\n }\n this.#token = await TwitchAuth.validateToken(token.access_token).then(getTwurpleProxy).then(this.#setToken)\n return this.#token\n }\n\n removeUser() {\n this.#token = null\n }\n\n async getAccessTokenForUser(user: string | number, ...scopeSets: string[][]) {\n if ((!scopeSets[0]) && (this.#token)) {\n return this.#token as AccessTokenWithUserId\n }\n for (const scopes of scopeSets) {\n if (hasScopes(this.#token, ...scopes)) {\n return this.#token as AccessTokenWithUserId\n }\n }\n this.#token = await TwitchAuth.getUserTokenPassive(this.clientId, ...(scopeSets[0] || [])).then(getTwurpleProxy).then(this.#setToken)\n return this.#token as AccessTokenWithUserId\n }\n\n async getAnyAccessToken(user: string | number) {\n return this.#token || TwitchAuth.getAppToken(this.clientId).then(getTwurpleProxy)\n }\n\n getCurrentScopesForUser(user: string | number) {\n if (!this.#token || this.#token instanceof Promise) {\n return []\n }\n return this.#token.scope\n }\n\n async refreshAccessTokenForUser(user: string | number) {\n this.#token = await TwitchAuth.refreshToken(this.clientId, this.#token.refresh_token).then(this.#setToken)\n return this.#token as AccessTokenWithUserId\n }\n}"], - "mappings": "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", - "names": ["require_fetch_retry_umd", "__commonJSMin", "exports", "module", "global", "factory", "fetchRetry", "fetch", "defaults", "ArgumentError", "isPositiveInteger", "baseDefaults", "input", "init", "retries", "retryDelay", "retryOn", "resolve", "reject", "wrappedFetch", "attempt", "_input", "response", "retryOnResponse", "retry", "error", "delay", "value", "message", "import_fetch_retry", "fetch", "fetch_retry", "attempts", "redirect_uri", "proxy_uri", "stamp", "token", "getAppToken", "client_id", "searchParams", "response", "requestAuthCode", "client_id", "scopes", "url", "redirect_uri", "exchangeCode", "code", "searchParams", "fetch", "proxy_uri", "response", "token", "stamp", "validateToken", "access_token", "refreshToken", "refresh_token", "getUserToken", "getUserTokenPassive", "params", "error_message", "getTwurpleProxy", "token", "target", "name", "receiver", "letter", "hasScopes", "scopes", "scope", "_token", "_setToken", "SugoiAuthProvider", "client_id", "__privateAdd", "__privateSet", "getUserToken", "__privateGet", "refreshToken", "validateToken", "user", "scopeSets", "getUserTokenPassive", "getAppToken"] -} diff --git a/static/TwitchAuth.js b/static/TwitchAuth.js deleted file mode 100644 index 90211c9..0000000 --- a/static/TwitchAuth.js +++ /dev/null @@ -1,2 +0,0 @@ -var D=Object.create;var x=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var U=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var E=(r,t)=>()=>(t||r((t={exports:{}}).exports,t),t.exports);var L=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of S(t))!q.call(r,o)&&o!==e&&x(r,o,{get:()=>t[o],enumerable:!(n=R(t,o))||n.enumerable});return r};var z=(r,t,e)=>(e=r!=null?D(U(r)):{},L(t||!r||!r.__esModule?x(e,"default",{value:r,enumerable:!0}):e,r));var v=E((k,_)=>{(function(r,t){typeof k=="object"&&typeof _<"u"?_.exports=t():typeof define=="function"&&define.amd?define(t):(r=typeof globalThis<"u"?globalThis:r||self,r.fetchRetry=t())})(k,function(){"use strict";var r=function(n,o){if(o=o||{},typeof n!="function")throw new e("fetch must be a function");if(typeof o!="object")throw new e("defaults must be an object");if(o.retries!==void 0&&!t(o.retries))throw new e("retries must be a positive integer");if(o.retryDelay!==void 0&&!t(o.retryDelay)&&typeof o.retryDelay!="function")throw new e("retryDelay must be a positive integer or a function returning a positive integer");if(o.retryOn!==void 0&&!Array.isArray(o.retryOn)&&typeof o.retryOn!="function")throw new e("retryOn property expects an array or function");var A={retries:3,retryDelay:1e3,retryOn:[]};return o=Object.assign(A,o),function(g,i){var l=o.retries,y=o.retryDelay,u=o.retryOn;if(i&&i.retries!==void 0)if(t(i.retries))l=i.retries;else throw new e("retries must be a positive integer");if(i&&i.retryDelay!==void 0)if(t(i.retryDelay)||typeof i.retryDelay=="function")y=i.retryDelay;else throw new e("retryDelay must be a positive integer or a function returning a positive integer");if(i&&i.retryOn)if(Array.isArray(i.retryOn)||typeof i.retryOn=="function")u=i.retryOn;else throw new e("retryOn property expects an array or function");return new Promise(function(w,h){var P=function(s){var m=typeof Request<"u"&&g instanceof Request?g.clone():g;n(m,i).then(function(a){if(Array.isArray(u)&&u.indexOf(a.status)===-1)w(a);else if(typeof u=="function")try{return Promise.resolve(u(s,null,a)).then(function(c){c?p(s,null,a):w(a)}).catch(h)}catch(c){h(c)}else s=0}function e(n){this.name="ArgumentError",this.message=n}return r})});var O=z(v()),d=(0,O.default)(globalThis.fetch,{retries:10,retryDelay:r=>r*1e3}),f=location.origin+location.pathname,T=new URL("/oauth2/token",import.meta.url);function b(r){return r.obtainment_timestamp=Date.now(),r}function J(r){let t=new URLSearchParams({client_id:r,grant_type:"client_credentials"});return d(T,{method:"POST",body:t.toString(),headers:{"content-type":"application/x-www-form-urlencoded"}}).then(async function(e){if(!e.ok)throw new Error(await e.text());let n=await e.json();return b(n)})}function K(r,...t){console.debug("requesting access token");let e=new URL("https://id.twitch.tv/oauth2/authorize");e.searchParams.append("response_type","token"),e.searchParams.append("client_id",r),e.searchParams.append("scope",t.join(" ")),location.assign(e+"&redirect_uri="+f)}function j(r,...t){console.debug("requesting authorization code");let e=new URL("https://id.twitch.tv/oauth2/authorize");return e.searchParams.append("response_type","code"),e.searchParams.append("client_id",r),e.searchParams.append("scope",t.join(" ").trim()),location.assign(e+"&redirect_uri="+f),new Promise(()=>{})}function C(r,t){console.debug("exchanging authorization code");let e=new URLSearchParams({client_id:r,code:t,grant_type:"authorization_code"});return d(T,{method:"POST",body:e.toString()+"&redirect_uri="+f,headers:{"content-type":"application/x-www-form-urlencoded"}}).then(async function(n){if(!n.ok)throw new Error(await n.text());let o=await n.json();return b(o)})}async function I(r){return console.debug("validating token"),d("https://id.twitch.tv/oauth2/validate",{headers:{authorization:"OAuth "+r}}).then(async t=>{if(!t.ok)throw new Error(await t.text());let e=await t.json();return e.access_token=r,e.scope=e.scopes,delete e.scopes,e.token_type="bearer",b(e)})}function F(r,t){console.debug("refreshing token");let e=new URLSearchParams({client_id:r,grant_type:"refresh_token",refresh_token:t});return d(T,{method:"POST",body:e.toString(),headers:{"content-type":"application/x-www-form-urlencoded"}}).then(async function(n){if(!n.ok)throw new Error(await n.text());return await n.json()})}async function N(r,...t){let e=await B(r,...t);return e||j(r,...t)}async function B(r,...t){console.debug("scopes requested:",...t);let e=new URLSearchParams(location.search+"&"+location.hash.substring(1));if(e.has("code")){let n=e.get("code");return history.replaceState(null,"",f),C(r,n)}if(e.has("refresh_token"))return F(r,e.get("refresh_token"));if(e.has("access_token"))return I(e.get("access_token"));if(e.has("error")){let n=e.get("error")+": "+e.get("error_description");throw history.replaceState(null,"",f),new Error(n)}return null}var M=N;export{M as default,C as exchangeCode,J as getAppToken,N as getUserToken,B as getUserTokenPassive,F as refreshToken,K as requestAccessToken,j as requestAuthCode,I as validateToken}; -//# sourceMappingURL=TwitchAuth.js.map diff --git a/static/TwitchAuth.js.map b/static/TwitchAuth.js.map deleted file mode 100644 index 70895d7..0000000 --- a/static/TwitchAuth.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../node_modules/fetch-retry/dist/fetch-retry.umd.js", "../static_src/TwitchAuth.ts"], - "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.fetchRetry = factory());\n})(this, (function () { 'use strict';\n\n var fetchRetry = function (fetch, defaults) {\n defaults = defaults || {};\n if (typeof fetch !== 'function') {\n throw new ArgumentError('fetch must be a function');\n }\n\n if (typeof defaults !== 'object') {\n throw new ArgumentError('defaults must be an object');\n }\n\n if (defaults.retries !== undefined && !isPositiveInteger(defaults.retries)) {\n throw new ArgumentError('retries must be a positive integer');\n }\n\n if (defaults.retryDelay !== undefined && !isPositiveInteger(defaults.retryDelay) && typeof defaults.retryDelay !== 'function') {\n throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');\n }\n\n if (defaults.retryOn !== undefined && !Array.isArray(defaults.retryOn) && typeof defaults.retryOn !== 'function') {\n throw new ArgumentError('retryOn property expects an array or function');\n }\n\n var baseDefaults = {\n retries: 3,\n retryDelay: 1000,\n retryOn: [],\n };\n\n defaults = Object.assign(baseDefaults, defaults);\n\n return function fetchRetry(input, init) {\n var retries = defaults.retries;\n var retryDelay = defaults.retryDelay;\n var retryOn = defaults.retryOn;\n\n if (init && init.retries !== undefined) {\n if (isPositiveInteger(init.retries)) {\n retries = init.retries;\n } else {\n throw new ArgumentError('retries must be a positive integer');\n }\n }\n\n if (init && init.retryDelay !== undefined) {\n if (isPositiveInteger(init.retryDelay) || (typeof init.retryDelay === 'function')) {\n retryDelay = init.retryDelay;\n } else {\n throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');\n }\n }\n\n if (init && init.retryOn) {\n if (Array.isArray(init.retryOn) || (typeof init.retryOn === 'function')) {\n retryOn = init.retryOn;\n } else {\n throw new ArgumentError('retryOn property expects an array or function');\n }\n }\n\n // eslint-disable-next-line no-undef\n return new Promise(function (resolve, reject) {\n var wrappedFetch = function (attempt) {\n // As of node 18, this is no longer needed since node comes with native support for fetch:\n /* istanbul ignore next */\n var _input =\n typeof Request !== 'undefined' && input instanceof Request\n ? input.clone()\n : input;\n fetch(_input, init)\n .then(function (response) {\n if (Array.isArray(retryOn) && retryOn.indexOf(response.status) === -1) {\n resolve(response);\n } else if (typeof retryOn === 'function') {\n try {\n // eslint-disable-next-line no-undef\n return Promise.resolve(retryOn(attempt, null, response))\n .then(function (retryOnResponse) {\n if(retryOnResponse) {\n retry(attempt, null, response);\n } else {\n resolve(response);\n }\n }).catch(reject);\n } catch (error) {\n reject(error);\n }\n } else {\n if (attempt < retries) {\n retry(attempt, null, response);\n } else {\n resolve(response);\n }\n }\n })\n .catch(function (error) {\n if (typeof retryOn === 'function') {\n try {\n // eslint-disable-next-line no-undef\n Promise.resolve(retryOn(attempt, error, null))\n .then(function (retryOnResponse) {\n if(retryOnResponse) {\n retry(attempt, error, null);\n } else {\n reject(error);\n }\n })\n .catch(function(error) {\n reject(error);\n });\n } catch(error) {\n reject(error);\n }\n } else if (attempt < retries) {\n retry(attempt, error, null);\n } else {\n reject(error);\n }\n });\n };\n\n function retry(attempt, error, response) {\n var delay = (typeof retryDelay === 'function') ?\n retryDelay(attempt, error, response) : retryDelay;\n setTimeout(function () {\n wrappedFetch(++attempt);\n }, delay);\n }\n\n wrappedFetch(0);\n });\n };\n };\n\n function isPositiveInteger(value) {\n return Number.isInteger(value) && value >= 0;\n }\n\n function ArgumentError(message) {\n this.name = 'ArgumentError';\n this.message = message;\n }\n\n return fetchRetry;\n\n}));\n", "import fetch_retry from 'fetch-retry'\nconst fetch = fetch_retry(globalThis.fetch, {\n retries: 10,\n retryDelay: attempts => attempts * 1000\n})\n\nexport interface TwitchToken {\n access_token: string\n expires_in: number\n obtainment_timestamp: number\n token_type: string\n user_id?: number\n scope?: Array\n refresh_token?: string\n login?: string\n client_id?: string\n}\n\nexport interface AuthCode {\n code: string\n scope: string\n}\n\nconst redirect_uri = location.origin + location.pathname\nconst proxy_uri = new URL('/oauth2/token', import.meta.url)\n\n/**\n * Timestamp and return the token\n * @param {TwitchToken} token \n * @returns {TwitchToken}\n */\nfunction stamp(token: TwitchToken): TwitchToken {\n token.obtainment_timestamp = Date.now()\n return token\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#client-credentials-grant-flow\n * @param {string} client_id \n * @returns {Promise}\n */\nexport function getAppToken(client_id: string): Promise {\n const searchParams = new URLSearchParams({\n client_id: client_id,\n grant_type: 'client_credentials'\n })\n return fetch(proxy_uri, {\n method: 'POST',\n body: searchParams.toString(),\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\n }).then(async function (response) {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n const token = await response.json()\n return stamp(token)\n })\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#implicit-grant-flow\n * @param {string} client_id \n * @param {Array|string} scopes \n * @returns {Promise}\n */\nexport function requestAccessToken(client_id: string, ...scopes: Array) {\n console.debug('requesting access token')\n const url = new URL('https://id.twitch.tv/oauth2/authorize')\n url.searchParams.append('response_type', 'token')\n url.searchParams.append('client_id', client_id)\n url.searchParams.append('scope', scopes.join(' '))\n location.assign(url + '&redirect_uri=' + redirect_uri)\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#get-the-user-to-authorize-your-app\n * @param {string} client_id \n * @param {Array|string} scopes \n * @returns {Promise}\n */\nexport function requestAuthCode(client_id: string, ...scopes: Array): Promise {\n console.debug('requesting authorization code')\n const url = new URL('https://id.twitch.tv/oauth2/authorize')\n url.searchParams.append('response_type', 'code')\n url.searchParams.append('client_id', client_id)\n url.searchParams.append('scope', scopes.join(' ').trim())\n location.assign(url + '&redirect_uri=' + redirect_uri)\n return new Promise(()=>{})\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#use-the-authorization-code-to-get-a-token\n * @param {string} client_id \n * @param {string} code \n * @returns {Promise}\n */\nexport function exchangeCode(client_id: string, code: string): Promise {\n console.debug('exchanging authorization code')\n const searchParams = new URLSearchParams({\n client_id: client_id,\n code: code,\n grant_type: 'authorization_code'\n })\n return fetch(proxy_uri, {\n method: 'POST',\n body: searchParams.toString() + '&redirect_uri=' + redirect_uri,\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\n }).then(async function (response) {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n const token = await response.json()\n return stamp(token)\n })\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/validate-tokens/#how-to-validate-a-token\n * @param {string} access_token \n * @returns {TwitchToken}\n */\nexport async function validateToken(access_token: string): Promise {\n console.debug('validating token')\n return fetch('https://id.twitch.tv/oauth2/validate', {\n headers: { authorization: 'OAuth ' + access_token }\n }).then(async response => {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n /** @type {TwitchToken} */\n const token: any = await response.json()\n token.access_token = access_token\n token.scope = token.scopes\n delete token.scopes\n token.token_type = 'bearer'\n return stamp(token)\n })\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/refresh-tokens/#how-to-use-a-refresh-token\n * @param {string} client_id \n * @param {string} refresh_token \n * @returns {Promise}\n */\nexport function refreshToken(client_id: string, refresh_token: string): Promise {\n console.debug('refreshing token')\n const searchParams = new URLSearchParams({\n client_id: client_id,\n grant_type: 'refresh_token',\n refresh_token: refresh_token\n })\n return fetch(proxy_uri, {\n method: 'POST',\n body: searchParams.toString(),\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\n }).then(async function (response) {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n return await response.json()\n })\n}\n\n/**\n * This function checks the url search parameters and hash for an auth code,\n * refresh token, access token, or error message, in that order,\n * and if it finds none of those, starts the auth code grant flow.\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#authorization-code-grant-flow\n * @param {string} client_id \n * @returns {TwitchToken}\n */\nexport async function getUserToken(client_id: string, ...scopes): Promise {\n const token=await getUserTokenPassive(client_id, ...scopes)\n if(!token){\n return requestAuthCode(client_id, ...scopes)\n }\n return token\n}\n\n/**\n * This function checks the url search parameters and hash for an auth code,\n * refresh token, access token, or error message, in that order.\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#authorization-code-grant-flow\n * @param {string} client_id \n * @returns {TwitchToken}\n */\nexport async function getUserTokenPassive(client_id: string, ...scopes): Promise{\n console.debug('scopes requested:',...scopes)\n const params = new URLSearchParams(location.search + '&' + location.hash.substring(1))\n if (params.has('code')) {\n const code = params.get('code')\n history.replaceState(null, '', redirect_uri)\n return exchangeCode(client_id, code)\n }\n if (params.has('refresh_token')) {\n return refreshToken(client_id, params.get('refresh_token'))\n }\n if (params.has('access_token')) {\n return validateToken(params.get('access_token'))\n }\n if (params.has('error')) {\n const error_message = params.get('error') + ': ' + params.get('error_description')\n history.replaceState(null, '', redirect_uri)\n throw new Error(error_message)\n }\n return null\n}\n\nexport default getUserToken"], - "mappings": "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", - "names": ["require_fetch_retry_umd", "__commonJSMin", "exports", "module", "global", "factory", "fetchRetry", "fetch", "defaults", "ArgumentError", "isPositiveInteger", "baseDefaults", "input", "init", "retries", "retryDelay", "retryOn", "resolve", "reject", "wrappedFetch", "attempt", "_input", "response", "retryOnResponse", "retry", "error", "delay", "value", "message", "import_fetch_retry", "fetch", "fetch_retry", "attempts", "redirect_uri", "proxy_uri", "stamp", "token", "getAppToken", "client_id", "searchParams", "response", "requestAccessToken", "scopes", "url", "requestAuthCode", "exchangeCode", "code", "validateToken", "access_token", "refreshToken", "refresh_token", "getUserToken", "getUserTokenPassive", "params", "error_message", "TwitchAuth_default"] -} diff --git a/static/WebStorage.js b/static/WebStorage.js deleted file mode 100644 index d7d61de..0000000 --- a/static/WebStorage.js +++ /dev/null @@ -1,3 +0,0 @@ -var d=i=>{throw TypeError(i)};var o=(i,t,h)=>t.has(i)||d("Cannot "+h);var n=(i,t,h)=>(o(i,t,"read from private field"),h?h.call(i):t.get(i)),c=(i,t,h)=>t.has(i)?d("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(i):t.set(i,h),u=(i,t,h,e)=>(o(i,t,"write to private field"),e?e.call(i,h):t.set(i,h),h);var l,r,a,s,w=class{constructor(t,h=(e,f)=>globalThis.fetch(e,f)){c(this,l,new URL(import.meta.url).origin);c(this,r,null);c(this,a,null);c(this,s,null);u(this,s,h),u(this,r,t),t.getAccessTokenForUser(void 0).then(e=>caches.open(e.userId+"/"+t.clientId)).then(e=>u(this,a,e))}async fetch(t,h={}){if(t=new URL(t,n(this,l)),t.origin==n(this,l)){let e=await n(this,r).getAccessTokenForUser(void 0);h.headers||(h.headers={}),h.headers.authorization="OAuth "+e.accessToken}if("method"in h)switch(h.method){case"PUT":case"POST":{let e=await n(this,s).call(this,t,h);if(!e.ok)return e;let f=await new Request(t,h).blob();return n(this,a).put(t,new Response(f)),e}case"DELETE":{let e=await n(this,s).call(this,t,h);return e.ok&&n(this,a).delete(t),e}}return n(this,s).call(this,t,h).then(async e=>{if(e.status>=500)throw new Error(e.statusText+` -`+await e.text());return n(this,a).put(t,e.clone()),e}).catch(e=>(console.warn(e),n(this,a).match(t)))}};l=new WeakMap,r=new WeakMap,a=new WeakMap,s=new WeakMap;export{w as default}; -//# sourceMappingURL=WebStorage.js.map diff --git a/static/WebStorage.js.map b/static/WebStorage.js.map deleted file mode 100644 index 2193f42..0000000 --- a/static/WebStorage.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../static_src/WebStorage.ts"], - "sourcesContent": ["/**\n * @callback fetch\n * @param {RequestInfo} resource\n * @param {RequestInit} options\n * @returns {Promise}\n */\n\nexport default class WebStorage {\n\n #origin = new URL(import.meta.url).origin\n #auth_provider: import('@twurple/auth').AuthProvider = null;\n #cache: Cache = null\n #fetch: typeof globalThis.fetch = null\n\n /**\n * Creates a fetch request wrapper that returns cached responses when the server can't be reached.\n * When only a path is provided, the origin defaults to the same origin this module was loaded from.\n * When the origin matches this script, authorization headers are added automatically.\n * You can also use this for GET requests to any orgigin, but other methods may have unknown behavior.\n * @param {import('@twurple/auth').AuthProvider} auth_provider used to add the authentication header to requests for web storage\n * @param {fetch} fetch defaults to `globalThis.fetch`, allows you to further customize fetch behavior via chaining, for example with `fetch-retry`\n */\n constructor(auth_provider: import('@twurple/auth').AuthProvider, fetch: typeof globalThis.fetch = (resource,options)=>{return globalThis.fetch(resource,options)}) {\n this.#fetch = fetch\n this.#auth_provider = auth_provider\n auth_provider.getAccessTokenForUser(undefined)\n .then(token => caches.open(token.userId + '/' + auth_provider.clientId))\n .then(cache => this.#cache = cache)\n }\n\n /**\n * \n * @param {String | URL} resource \n * @param {RequestInit} options \n */\n async fetch(resource: string | URL, options: RequestInit={}) {\n resource = new URL(resource, this.#origin)\n if (resource.origin == this.#origin) {\n const token = await this.#auth_provider.getAccessTokenForUser(undefined)\n if (!options.headers) {\n options.headers = {}\n }\n options.headers['authorization'] = 'OAuth ' + token.accessToken\n }\n if ('method' in options) {\n switch (options.method) {\n case 'PUT':\n case 'POST': {\n const response = await this.#fetch(resource, options)\n if (!response.ok) {\n return response\n }\n const blob = await new Request(resource, options).blob()\n this.#cache.put(resource, new Response(blob))\n return response\n }\n case 'DELETE': {\n const response = await this.#fetch(resource, options)\n if (!response.ok) {\n return response\n }\n this.#cache.delete(resource)\n return response\n }\n }\n }\n return this.#fetch(resource, options)\n .then(async response => {\n if (response.status >= 500) {\n throw new Error(response.statusText + '\\n' + await response.text())\n }\n this.#cache.put(resource, response.clone())\n return response\n }).catch(error => {\n console.warn(error)\n return this.#cache.match(resource)\n }\n )\n }\n}"], - "mappings": "2UAAA,IAAAA,EAAAC,EAAAC,EAAAC,EAOqBC,EAArB,KAAgC,CAe5B,YAAYC,EAAqDC,EAAiC,CAACC,EAASC,IAAkB,WAAW,MAAMD,EAASC,CAAO,EAAI,CAbnKC,EAAA,KAAAT,EAAU,IAAI,IAAI,YAAY,GAAG,EAAE,QACnCS,EAAA,KAAAR,EAAuD,MACvDQ,EAAA,KAAAP,EAAgB,MAChBO,EAAA,KAAAN,EAAkC,MAW9BO,EAAA,KAAKP,EAASG,GACdI,EAAA,KAAKT,EAAiBI,GACtBA,EAAc,sBAAsB,MAAS,EACxC,KAAKM,GAAS,OAAO,KAAKA,EAAM,OAAS,IAAMN,EAAc,QAAQ,CAAC,EACtE,KAAKO,GAASF,EAAA,KAAKR,EAASU,EAAK,CAC1C,CAOA,MAAM,MAAML,EAAwBC,EAAqB,CAAC,EAAG,CAEzD,GADAD,EAAW,IAAI,IAAIA,EAAUM,EAAA,KAAKb,EAAO,EACrCO,EAAS,QAAUM,EAAA,KAAKb,GAAS,CACjC,IAAMW,EAAQ,MAAME,EAAA,KAAKZ,GAAe,sBAAsB,MAAS,EAClEO,EAAQ,UACTA,EAAQ,QAAU,CAAC,GAEvBA,EAAQ,QAAQ,cAAmB,SAAWG,EAAM,WACxD,CACA,GAAI,WAAYH,EACZ,OAAQA,EAAQ,OAAQ,CACpB,IAAK,MACL,IAAK,OAAQ,CACT,IAAMM,EAAW,MAAMD,EAAA,KAAKV,GAAL,UAAYI,EAAUC,GAC7C,GAAI,CAACM,EAAS,GACV,OAAOA,EAEX,IAAMC,EAAO,MAAM,IAAI,QAAQR,EAAUC,CAAO,EAAE,KAAK,EACvD,OAAAK,EAAA,KAAKX,GAAO,IAAIK,EAAU,IAAI,SAASQ,CAAI,CAAC,EACrCD,CACX,CACA,IAAK,SAAU,CACX,IAAMA,EAAW,MAAMD,EAAA,KAAKV,GAAL,UAAYI,EAAUC,GAC7C,OAAKM,EAAS,IAGdD,EAAA,KAAKX,GAAO,OAAOK,CAAQ,EACpBO,CACX,CACJ,CAEJ,OAAOD,EAAA,KAAKV,GAAL,UAAYI,EAAUC,GACxB,KAAK,MAAMM,GAAY,CACpB,GAAIA,EAAS,QAAU,IACnB,MAAM,IAAI,MAAMA,EAAS,WAAa;AAAA,EAAO,MAAMA,EAAS,KAAK,CAAC,EAEtE,OAAAD,EAAA,KAAKX,GAAO,IAAIK,EAAUO,EAAS,MAAM,CAAC,EACnCA,CACX,CAAC,EAAE,MAAME,IACL,QAAQ,KAAKA,CAAK,EACXH,EAAA,KAAKX,GAAO,MAAMK,CAAQ,EAEzC,CACJ,CACJ,EAtEIP,EAAA,YACAC,EAAA,YACAC,EAAA,YACAC,EAAA", - "names": ["_origin", "_auth_provider", "_cache", "_fetch", "WebStorage", "auth_provider", "fetch", "resource", "options", "__privateAdd", "__privateSet", "token", "cache", "__privateGet", "response", "blob", "error"] -} diff --git a/static/tba.js b/static/tba.js deleted file mode 100644 index 728d43b..0000000 --- a/static/tba.js +++ /dev/null @@ -1,2 +0,0 @@ -var z=Object.create;var O=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var C=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var H=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var B=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of L(t))!I.call(e,n)&&n!==r&&O(e,n,{get:()=>t[n],enumerable:!(o=E(t,n))||o.enumerable});return e};var F=(e,t,r)=>(r=e!=null?z(C(e)):{},B(t||!e||!e.__esModule?O(r,"default",{value:e,enumerable:!0}):r,e));var D=H((T,k)=>{(function(e,t){typeof T=="object"&&typeof k<"u"?k.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self,e.fetchRetry=t())})(T,function(){"use strict";var e=function(o,n){if(n=n||{},typeof o!="function")throw new r("fetch must be a function");if(typeof n!="object")throw new r("defaults must be an object");if(n.retries!==void 0&&!t(n.retries))throw new r("retries must be a positive integer");if(n.retryDelay!==void 0&&!t(n.retryDelay)&&typeof n.retryDelay!="function")throw new r("retryDelay must be a positive integer or a function returning a positive integer");if(n.retryOn!==void 0&&!Array.isArray(n.retryOn)&&typeof n.retryOn!="function")throw new r("retryOn property expects an array or function");var j={retries:3,retryDelay:1e3,retryOn:[]};return n=Object.assign(j,n),function(d,i){var w=n.retries,y=n.retryDelay,h=n.retryOn;if(i&&i.retries!==void 0)if(t(i.retries))w=i.retries;else throw new r("retries must be a positive integer");if(i&&i.retryDelay!==void 0)if(t(i.retryDelay)||typeof i.retryDelay=="function")y=i.retryDelay;else throw new r("retryDelay must be a positive integer or a function returning a positive integer");if(i&&i.retryOn)if(Array.isArray(i.retryOn)||typeof i.retryOn=="function")h=i.retryOn;else throw new r("retryOn property expects an array or function");return new Promise(function(m,f){var v=function(c){var _=typeof Request<"u"&&d instanceof Request?d.clone():d;o(_,i).then(function(a){if(Array.isArray(h)&&h.indexOf(a.status)===-1)m(a);else if(typeof h=="function")try{return Promise.resolve(h(c,null,a)).then(function(u){u?g(c,null,a):m(a)}).catch(f)}catch(u){f(u)}else c=0}function r(o){this.name="ArgumentError",this.message=o}return e})});var R=F(D()),x=(0,R.default)(globalThis.fetch,{retries:10,retryDelay:e=>e*1e3}),l=location.origin+location.pathname,S=new URL("/oauth2/token",import.meta.url);function U(e){return e.obtainment_timestamp=Date.now(),e}function b(e,...t){console.debug("requesting authorization code");let r=new URL("https://id.twitch.tv/oauth2/authorize");return r.searchParams.append("response_type","code"),r.searchParams.append("client_id",e),r.searchParams.append("scope",t.join(" ").trim()),location.assign(r+"&redirect_uri="+l),new Promise(()=>{})}function P(e,t){console.debug("exchanging authorization code");let r=new URLSearchParams({client_id:e,code:t,grant_type:"authorization_code"});return x(S,{method:"POST",body:r.toString()+"&redirect_uri="+l,headers:{"content-type":"application/x-www-form-urlencoded"}}).then(async function(o){if(!o.ok)throw new Error(await o.text());let n=await o.json();return U(n)})}async function A(e){return console.debug("validating token"),x("https://id.twitch.tv/oauth2/validate",{headers:{authorization:"OAuth "+e}}).then(async t=>{if(!t.ok)throw new Error(await t.text());let r=await t.json();return r.access_token=e,r.scope=r.scopes,delete r.scopes,r.token_type="bearer",U(r)})}function p(e,t){console.debug("refreshing token");let r=new URLSearchParams({client_id:e,grant_type:"refresh_token",refresh_token:t});return x(S,{method:"POST",body:r.toString(),headers:{"content-type":"application/x-www-form-urlencoded"}}).then(async function(o){if(!o.ok)throw new Error(await o.text());return await o.json()})}async function q(e,...t){let r=await N(e,...t);return r||b(e,...t)}async function N(e,...t){console.debug("scopes requested:",...t);let r=new URLSearchParams(location.search+"&"+location.hash.substring(1));if(r.has("code")){let o=r.get("code");return history.replaceState(null,"",l),P(e,o)}if(r.has("refresh_token"))return p(e,r.get("refresh_token"));if(r.has("access_token"))return A(r.get("access_token"));if(r.has("error")){let o=r.get("error")+": "+r.get("error_description");throw history.replaceState(null,"",l),new Error(o)}return null}var s=null;function X(e,t,r=location.origin+location.pathname){return b(e,...t.split(" "))}function Y(){return Object.fromEntries(new URLSearchParams(location.search))}async function Z(e,t,r=location.origin+location.pathname){return e=e,s=await P(e,t),s.client_id=e,s}function J(e){return{Authorization:"Bearer "+e.access_token,"Client-ID":e.client_id}}async function K(e){let t=await A(e.access_token);return Object.assign(e,t),e.scope=t.scope,e.auth_headers=J(e),s=e,s}function $(e,t){return s=t,s}function ee(e){return s}async function te(e,t){return s=await p(e,t),s}function M(e,t){return setTimeout(()=>{p(e,t.refresh_token).then(r=>Object.assign(t,r))},t.expires_in*999)}async function Q(e,t="",r=location.origin+location.pathname,o=!1){return s=await q(e,...t.split(" ")).then(K),M(e,s),s}var re=Q;export{re as default,Z as fetch_tokens,J as get_headers,ee as get_local_tokens,Q as get_tokens,Y as get_url_params,te as refresh_tokens,X as request_auth,$ as set_local_tokens,M as set_refresh_timeout,K as validate_tokens}; -//# sourceMappingURL=tba.js.map diff --git a/static/tba.js.map b/static/tba.js.map deleted file mode 100644 index 9c4ee3d..0000000 --- a/static/tba.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../node_modules/fetch-retry/dist/fetch-retry.umd.js", "../static_src/TwitchAuth.ts", "../static_src/tba.ts"], - "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.fetchRetry = factory());\n})(this, (function () { 'use strict';\n\n var fetchRetry = function (fetch, defaults) {\n defaults = defaults || {};\n if (typeof fetch !== 'function') {\n throw new ArgumentError('fetch must be a function');\n }\n\n if (typeof defaults !== 'object') {\n throw new ArgumentError('defaults must be an object');\n }\n\n if (defaults.retries !== undefined && !isPositiveInteger(defaults.retries)) {\n throw new ArgumentError('retries must be a positive integer');\n }\n\n if (defaults.retryDelay !== undefined && !isPositiveInteger(defaults.retryDelay) && typeof defaults.retryDelay !== 'function') {\n throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');\n }\n\n if (defaults.retryOn !== undefined && !Array.isArray(defaults.retryOn) && typeof defaults.retryOn !== 'function') {\n throw new ArgumentError('retryOn property expects an array or function');\n }\n\n var baseDefaults = {\n retries: 3,\n retryDelay: 1000,\n retryOn: [],\n };\n\n defaults = Object.assign(baseDefaults, defaults);\n\n return function fetchRetry(input, init) {\n var retries = defaults.retries;\n var retryDelay = defaults.retryDelay;\n var retryOn = defaults.retryOn;\n\n if (init && init.retries !== undefined) {\n if (isPositiveInteger(init.retries)) {\n retries = init.retries;\n } else {\n throw new ArgumentError('retries must be a positive integer');\n }\n }\n\n if (init && init.retryDelay !== undefined) {\n if (isPositiveInteger(init.retryDelay) || (typeof init.retryDelay === 'function')) {\n retryDelay = init.retryDelay;\n } else {\n throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');\n }\n }\n\n if (init && init.retryOn) {\n if (Array.isArray(init.retryOn) || (typeof init.retryOn === 'function')) {\n retryOn = init.retryOn;\n } else {\n throw new ArgumentError('retryOn property expects an array or function');\n }\n }\n\n // eslint-disable-next-line no-undef\n return new Promise(function (resolve, reject) {\n var wrappedFetch = function (attempt) {\n // As of node 18, this is no longer needed since node comes with native support for fetch:\n /* istanbul ignore next */\n var _input =\n typeof Request !== 'undefined' && input instanceof Request\n ? input.clone()\n : input;\n fetch(_input, init)\n .then(function (response) {\n if (Array.isArray(retryOn) && retryOn.indexOf(response.status) === -1) {\n resolve(response);\n } else if (typeof retryOn === 'function') {\n try {\n // eslint-disable-next-line no-undef\n return Promise.resolve(retryOn(attempt, null, response))\n .then(function (retryOnResponse) {\n if(retryOnResponse) {\n retry(attempt, null, response);\n } else {\n resolve(response);\n }\n }).catch(reject);\n } catch (error) {\n reject(error);\n }\n } else {\n if (attempt < retries) {\n retry(attempt, null, response);\n } else {\n resolve(response);\n }\n }\n })\n .catch(function (error) {\n if (typeof retryOn === 'function') {\n try {\n // eslint-disable-next-line no-undef\n Promise.resolve(retryOn(attempt, error, null))\n .then(function (retryOnResponse) {\n if(retryOnResponse) {\n retry(attempt, error, null);\n } else {\n reject(error);\n }\n })\n .catch(function(error) {\n reject(error);\n });\n } catch(error) {\n reject(error);\n }\n } else if (attempt < retries) {\n retry(attempt, error, null);\n } else {\n reject(error);\n }\n });\n };\n\n function retry(attempt, error, response) {\n var delay = (typeof retryDelay === 'function') ?\n retryDelay(attempt, error, response) : retryDelay;\n setTimeout(function () {\n wrappedFetch(++attempt);\n }, delay);\n }\n\n wrappedFetch(0);\n });\n };\n };\n\n function isPositiveInteger(value) {\n return Number.isInteger(value) && value >= 0;\n }\n\n function ArgumentError(message) {\n this.name = 'ArgumentError';\n this.message = message;\n }\n\n return fetchRetry;\n\n}));\n", "import fetch_retry from 'fetch-retry'\nconst fetch = fetch_retry(globalThis.fetch, {\n retries: 10,\n retryDelay: attempts => attempts * 1000\n})\n\nexport interface TwitchToken {\n access_token: string\n expires_in: number\n obtainment_timestamp: number\n token_type: string\n user_id?: number\n scope?: Array\n refresh_token?: string\n login?: string\n client_id?: string\n}\n\nexport interface AuthCode {\n code: string\n scope: string\n}\n\nconst redirect_uri = location.origin + location.pathname\nconst proxy_uri = new URL('/oauth2/token', import.meta.url)\n\n/**\n * Timestamp and return the token\n * @param {TwitchToken} token \n * @returns {TwitchToken}\n */\nfunction stamp(token: TwitchToken): TwitchToken {\n token.obtainment_timestamp = Date.now()\n return token\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#client-credentials-grant-flow\n * @param {string} client_id \n * @returns {Promise}\n */\nexport function getAppToken(client_id: string): Promise {\n const searchParams = new URLSearchParams({\n client_id: client_id,\n grant_type: 'client_credentials'\n })\n return fetch(proxy_uri, {\n method: 'POST',\n body: searchParams.toString(),\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\n }).then(async function (response) {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n const token = await response.json()\n return stamp(token)\n })\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#implicit-grant-flow\n * @param {string} client_id \n * @param {Array|string} scopes \n * @returns {Promise}\n */\nexport function requestAccessToken(client_id: string, ...scopes: Array) {\n console.debug('requesting access token')\n const url = new URL('https://id.twitch.tv/oauth2/authorize')\n url.searchParams.append('response_type', 'token')\n url.searchParams.append('client_id', client_id)\n url.searchParams.append('scope', scopes.join(' '))\n location.assign(url + '&redirect_uri=' + redirect_uri)\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#get-the-user-to-authorize-your-app\n * @param {string} client_id \n * @param {Array|string} scopes \n * @returns {Promise}\n */\nexport function requestAuthCode(client_id: string, ...scopes: Array): Promise {\n console.debug('requesting authorization code')\n const url = new URL('https://id.twitch.tv/oauth2/authorize')\n url.searchParams.append('response_type', 'code')\n url.searchParams.append('client_id', client_id)\n url.searchParams.append('scope', scopes.join(' ').trim())\n location.assign(url + '&redirect_uri=' + redirect_uri)\n return new Promise(()=>{})\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#use-the-authorization-code-to-get-a-token\n * @param {string} client_id \n * @param {string} code \n * @returns {Promise}\n */\nexport function exchangeCode(client_id: string, code: string): Promise {\n console.debug('exchanging authorization code')\n const searchParams = new URLSearchParams({\n client_id: client_id,\n code: code,\n grant_type: 'authorization_code'\n })\n return fetch(proxy_uri, {\n method: 'POST',\n body: searchParams.toString() + '&redirect_uri=' + redirect_uri,\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\n }).then(async function (response) {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n const token = await response.json()\n return stamp(token)\n })\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/validate-tokens/#how-to-validate-a-token\n * @param {string} access_token \n * @returns {TwitchToken}\n */\nexport async function validateToken(access_token: string): Promise {\n console.debug('validating token')\n return fetch('https://id.twitch.tv/oauth2/validate', {\n headers: { authorization: 'OAuth ' + access_token }\n }).then(async response => {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n /** @type {TwitchToken} */\n const token: any = await response.json()\n token.access_token = access_token\n token.scope = token.scopes\n delete token.scopes\n token.token_type = 'bearer'\n return stamp(token)\n })\n}\n\n/**\n * https://dev.twitch.tv/docs/authentication/refresh-tokens/#how-to-use-a-refresh-token\n * @param {string} client_id \n * @param {string} refresh_token \n * @returns {Promise}\n */\nexport function refreshToken(client_id: string, refresh_token: string): Promise {\n console.debug('refreshing token')\n const searchParams = new URLSearchParams({\n client_id: client_id,\n grant_type: 'refresh_token',\n refresh_token: refresh_token\n })\n return fetch(proxy_uri, {\n method: 'POST',\n body: searchParams.toString(),\n headers: { 'content-type': 'application/x-www-form-urlencoded' }\n }).then(async function (response) {\n if (!response.ok) {\n throw new Error(await response.text())\n }\n return await response.json()\n })\n}\n\n/**\n * This function checks the url search parameters and hash for an auth code,\n * refresh token, access token, or error message, in that order,\n * and if it finds none of those, starts the auth code grant flow.\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#authorization-code-grant-flow\n * @param {string} client_id \n * @returns {TwitchToken}\n */\nexport async function getUserToken(client_id: string, ...scopes): Promise {\n const token=await getUserTokenPassive(client_id, ...scopes)\n if(!token){\n return requestAuthCode(client_id, ...scopes)\n }\n return token\n}\n\n/**\n * This function checks the url search parameters and hash for an auth code,\n * refresh token, access token, or error message, in that order.\n * https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#authorization-code-grant-flow\n * @param {string} client_id \n * @returns {TwitchToken}\n */\nexport async function getUserTokenPassive(client_id: string, ...scopes): Promise{\n console.debug('scopes requested:',...scopes)\n const params = new URLSearchParams(location.search + '&' + location.hash.substring(1))\n if (params.has('code')) {\n const code = params.get('code')\n history.replaceState(null, '', redirect_uri)\n return exchangeCode(client_id, code)\n }\n if (params.has('refresh_token')) {\n return refreshToken(client_id, params.get('refresh_token'))\n }\n if (params.has('access_token')) {\n return validateToken(params.get('access_token'))\n }\n if (params.has('error')) {\n const error_message = params.get('error') + ': ' + params.get('error_description')\n history.replaceState(null, '', redirect_uri)\n throw new Error(error_message)\n }\n return null\n}\n\nexport default getUserToken", "import * as TwitchAuth from './TwitchAuth.ts'\n\ninterface AuthHeaders {\n 'Authorization': string,\n 'Client-ID': string\n}\n\ninterface Token extends TwitchAuth.TwitchToken {\n auth_headers: AuthHeaders\n}\n\nlet token: Token=null;\n\nexport function request_auth(client_id: string,scope: string,redirect_uri=location.origin+location.pathname){\n return TwitchAuth.requestAuthCode(client_id,...scope.split(' '))\n}\n\nexport function get_url_params(){\n return Object.fromEntries(new URLSearchParams(location.search))\n}\n\nexport async function fetch_tokens(client_id: string,code: string,redirect_uri=location.origin+location.pathname): Promise{\n client_id=client_id\n token=await TwitchAuth.exchangeCode(client_id,code) as Token\n token.client_id=client_id\n return token\n}\n\nexport function get_headers(tokens: Token): AuthHeaders{\n return {\n 'Authorization':'Bearer '+tokens.access_token,\n 'Client-ID':tokens.client_id\n }\n}\n\nexport async function validate_tokens(tokens: Token): Promise{\n const validation=await TwitchAuth.validateToken(tokens.access_token)\n Object.assign(tokens,validation)\n tokens.scope=validation.scope\n tokens.auth_headers=get_headers(tokens)\n token=tokens\n return token\n}\n\nexport function set_local_tokens(client_id: string,tokens: Token){\n token=tokens\n return token\n}\n\nexport function get_local_tokens(client_id: string){\n return token\n}\n\nexport async function refresh_tokens(client_id: string,refresh_token: string){\n token=await TwitchAuth.refreshToken(client_id,refresh_token) as Token\n return token\n}\n\nexport function set_refresh_timeout(client_id: string,tokens: Token){\n return setTimeout(()=>{\n TwitchAuth.refreshToken(client_id,tokens.refresh_token)\n .then(new_tokens=>Object.assign(tokens,new_tokens))\n },tokens.expires_in*999)\n}\n\nexport async function get_tokens(client_id: string,scope='',redirect_uri=location.origin+location.pathname,auth_return=false){\n token=await TwitchAuth.getUserToken(client_id,...scope.split(' ')).then(validate_tokens)\n set_refresh_timeout(client_id,token)\n return token\n}\n\nexport default get_tokens"], - "mappings": "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", - "names": ["require_fetch_retry_umd", "__commonJSMin", "exports", "module", "global", "factory", "fetchRetry", "fetch", "defaults", "ArgumentError", "isPositiveInteger", "baseDefaults", "input", "init", "retries", "retryDelay", "retryOn", "resolve", "reject", "wrappedFetch", "attempt", "_input", "response", "retryOnResponse", "retry", "error", "delay", "value", "message", "import_fetch_retry", "fetch", "fetch_retry", "attempts", "redirect_uri", "proxy_uri", "stamp", "token", "requestAuthCode", "client_id", "scopes", "url", "redirect_uri", "exchangeCode", "code", "searchParams", "fetch", "proxy_uri", "response", "token", "stamp", "validateToken", "access_token", "refreshToken", "refresh_token", "getUserToken", "getUserTokenPassive", "params", "error_message", "token", "request_auth", "client_id", "scope", "redirect_uri", "requestAuthCode", "get_url_params", "fetch_tokens", "code", "exchangeCode", "get_headers", "tokens", "validate_tokens", "validation", "validateToken", "set_local_tokens", "get_local_tokens", "refresh_tokens", "refresh_token", "refreshToken", "set_refresh_timeout", "new_tokens", "get_tokens", "auth_return", "getUserToken", "tba_default"] -}