diff --git a/types/passport-twitch-latest/index.d.ts b/types/passport-twitch-latest/index.d.ts new file mode 100644 index 0000000000..5075ff4a32 --- /dev/null +++ b/types/passport-twitch-latest/index.d.ts @@ -0,0 +1,89 @@ +// Type definitions for passport-twitch-latest 1.0 +// Project: https://github.com/sascha-beloborodov/passport-twitch +// Definitions by: Charlie Laabs +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// Minimum TypeScript Version: 3.5 + +import * as PassportOauth2 from 'passport-oauth2'; +import * as passport from 'passport'; +import * as e from 'express'; + +export class Strategy extends PassportOauth2 { + // Disabling this tslint rule as unifying the signatures makes the callback function default to inferring the + // longest callback which breaks the example config. See: https://github.com/Microsoft/TypeScript/issues/16867 + constructor(options: StrategyOptionsWithRequest, verify: VerifyFunctionWithRequest); + // tslint:disable-next-line unified-signatures + constructor(options: StrategyOptionsWithRequest, verify: VerifyFunctionWithRequestResults); + constructor(options: StrategyOptions, verify: VerifyFunction); + // tslint:disable-next-line unified-signatures + constructor(options: StrategyOptions, verify: VerifyFunctionWithResults); + + userProfile(accessToken: string, done: (err?: Error | null, profile?: TwitchProfile) => void): void; + authorize( + strategy: string | string[], + options: AuthenticateOptions, + callback?: (...args: any[]) => any, + ): AuthenticateRet; + authorize(strategy: string | string[], callback?: (...args: any[]) => any): AuthenticateRet; + authenticate(req: e.Request, options?: AuthenticateOptions): void; +} + +export class OAuth2Strategy extends Strategy {} + +export type Optional = Omit & Partial; + +export type StrategyOptions = Optional; +export type StrategyOptionsWithRequest = Optional< + PassportOauth2.StrategyOptionsWithRequest, + 'authorizationURL' | 'tokenURL' +>; + +export type VerifyFunction = ( + accessToken: string, + refreshToken: string, + profile: TwitchProfile, + verified: PassportOauth2.VerifyCallback, +) => void; +export type VerifyFunctionWithResults = ( + accessToken: string, + refreshToken: string, + results: any, + profile: TwitchProfile, + verified: PassportOauth2.VerifyCallback, +) => void; +export type VerifyFunctionWithRequest = ( + req: e.Request, + accessToken: string, + refreshToken: string, + profile: TwitchProfile, + verified: PassportOauth2.VerifyCallback, +) => void; +export type VerifyFunctionWithRequestResults = ( + req: e.Request, + accessToken: string, + refreshToken: string, + results: any, + profile: TwitchProfile, + verified: PassportOauth2.VerifyCallback, +) => void; + +export interface TwitchProfile { + id: string; + login: string; + display_name: string; + type: string; + broadcaster_type: string; + description: string; + profile_image_url: string; + offline_image_url: string; + view_count: number; + provider: string; +} + +export interface AuthenticateOptions extends passport.AuthenticateOptions { + forceVerify?: boolean; +} + +export interface AuthenticateRet { + force_verify?: boolean; +} diff --git a/types/passport-twitch-latest/passport-twitch-latest-tests.ts b/types/passport-twitch-latest/passport-twitch-latest-tests.ts new file mode 100644 index 0000000000..36fcef8f58 --- /dev/null +++ b/types/passport-twitch-latest/passport-twitch-latest-tests.ts @@ -0,0 +1,161 @@ +import { + Strategy as TwitchStrategy, + OAuth2Strategy as OtherStrategy, + StrategyOptions, + StrategyOptionsWithRequest, + TwitchProfile, + VerifyFunctionWithResults, + VerifyFunctionWithRequestResults, +} from 'passport-twitch-latest'; +import { VerifyCallback } from 'passport-oauth2'; +import { Request } from 'express'; + +const exampleStrategy = new TwitchStrategy( + { + clientID: '', + clientSecret: '', + callbackURL: '', + scope: '', + }, + (accessToken, refreshToken, profile, done) => { + done(new Error(), {}); + }, +); + +const exampleStrategyResults = new TwitchStrategy( + { + clientID: '', + clientSecret: '', + callbackURL: '', + scope: '', + }, + ((accessToken, refreshToken, results, profile, done) => { + done(new Error(), {}); + }) as VerifyFunctionWithResults, // We must cast this due to type inference: https://github.com/Microsoft/TypeScript/issues/16867 +); + +const exampleStrategyRequest = new TwitchStrategy( + { + clientID: '', + clientSecret: '', + callbackURL: '', + scope: '', + passReqToCallback: true, + }, + (req, accessToken, refreshToken, profile, done) => { + done(new Error(), {}); + }, +); + +const exampleStrategyRequestResults = new TwitchStrategy( + { + clientID: '', + clientSecret: '', + callbackURL: '', + scope: '', + passReqToCallback: true, + }, + ((req, accessToken, refreshToken, results, profile, done) => { + done(new Error(), {}); + }) as VerifyFunctionWithRequestResults, // We must cast this due to type inference: https://github.com/Microsoft/TypeScript/issues/16867 +); + +const strategyOptions1: StrategyOptions = { + callbackURL: 'http://www.example.com/callback', + clientID: 'dummy', + clientSecret: 'secret', +}; + +const twitchProfile: TwitchProfile = { + id: '', + login: '', + display_name: '', + type: '', + broadcaster_type: '', + description: '', + profile_image_url: '', + offline_image_url: '', + view_count: 0, + provider: '', +}; + +function verifyFunction1( + _accessToken: string, + _refreshToken: string, + _profile: TwitchProfile, + verifyCallback: VerifyCallback, +) { + verifyCallback(new Error('unimplemented')); +} + +function verifyFunction2( + _accessToken: string, + _refreshToken: string, + _results: any, + _profile: TwitchProfile, + verifyCallback: VerifyCallback, +) { + verifyCallback(new Error('unimplemented')); +} + +const strategy1: TwitchStrategy = new TwitchStrategy(strategyOptions1, verifyFunction1); + +const strategy2: TwitchStrategy = new TwitchStrategy(strategyOptions1, verifyFunction2); + +function verifyFunction3( + _req: Request, + _accessToken: string, + _refreshToken: string, + _profile: TwitchProfile, + verifyCallback: VerifyCallback, +) { + verifyCallback(undefined, { userid: '1' }); +} + +function verifyFunction4( + _req: Request, + _accessToken: string, + _refreshToken: string, + _results: any, + _profile: TwitchProfile, + verifyCallback: VerifyCallback, +) { + verifyCallback(undefined, { userid: '1' }); +} + +const strategyOptions2: StrategyOptionsWithRequest = { + clientID: 'dummy', + clientSecret: 'secret', + passReqToCallback: true, +}; + +const strategy3 = new OtherStrategy(strategyOptions2, verifyFunction3); + +const strategy4 = new OtherStrategy(strategyOptions2, verifyFunction4); + +class MyStrategy extends TwitchStrategy { + useProtectedProperty() { + this._oauth2.get('http://www.example.com/profile', 'token', err => err.statusCode); + this._oauth2.get('http://www.example.com/profile', 'token', (err, result) => result); + this._oauth2.get('http://www.example.com/profile', 'token', (err, result, response) => response); + } +} + +const strategyOptions3: StrategyOptions = { + authorizationURL: 'http://www.example.com/auth', + clientID: 'dummy', + clientSecret: 'secret', + tokenURL: 'http://www.example.com/token', + callbackURL: 'http://www.example.com/callback', + customHeaders: { + 'content-type': 'text/html', + }, + scope: ['scope1', 'scope2'], + scopeSeparator: ' ', + sessionKey: 'oauth', + state: { id: 1 }, + skipUserProfile: true, + pkce: false, +}; + +const strategy5: TwitchStrategy = new TwitchStrategy(strategyOptions3, verifyFunction2); diff --git a/types/passport-twitch-latest/tsconfig.json b/types/passport-twitch-latest/tsconfig.json new file mode 100644 index 0000000000..f06684a459 --- /dev/null +++ b/types/passport-twitch-latest/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "passport-twitch-latest-tests.ts" + ] +} diff --git a/types/passport-twitch-latest/tslint.json b/types/passport-twitch-latest/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/passport-twitch-latest/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }