forked from atinux/nuxt-auth-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
steam.ts
92 lines (80 loc) · 3.12 KB
/
steam.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import type { H3Event } from 'h3'
import { eventHandler, createError, getQuery, getRequestURL, sendRedirect } from 'h3'
import { withQuery } from 'ufo'
import { defu } from 'defu'
import { handleMissingConfiguration } from '../utils'
import { useRuntimeConfig } from '#imports'
import type { OAuthConfig } from '#auth-utils'
export interface OAuthSteamConfig {
/**
* Steam API Key
* @default process.env.NUXT_OAUTH_STEAM_API_KEY
* @see https://steamcommunity.com/dev
*/
apiKey?: string
/**
* Steam Open ID OAuth Authorization URL
* @default 'https://steamcommunity.com/openid/login'
*/
authorizationURL?: string
/**
* Redirect URL to to allow overriding for situations like prod failing to determine public hostname
* @default process.env.NUXT_OAUTH_STEAM_REDIRECT_URL or current URL
*/
redirectURL?: string
}
export function defineOAuthSteamEventHandler({ config, onSuccess, onError }: OAuthConfig<OAuthSteamConfig>) {
return eventHandler(async (event: H3Event) => {
config = defu(config, useRuntimeConfig(event).oauth?.steam, {
authorizationURL: 'https://steamcommunity.com/openid/login',
}) as OAuthSteamConfig
const query = getQuery<Record<string, string>>(event)
if (!config.apiKey) {
return handleMissingConfiguration(event, 'steam', ['apiKey'], onError)
}
if (!query['openid.claimed_id']) {
const redirectURL = config.redirectURL || getRequestURL(event).href
const steamOpenIdParams = {
'openid.ns': 'http://specs.openid.net/auth/2.0',
'openid.mode': 'checkid_setup',
'openid.return_to': redirectURL,
'openid.identity': 'http://specs.openid.net/auth/2.0/identifier_select',
'openid.claimed_id': 'http://specs.openid.net/auth/2.0/identifier_select',
}
// Redirect to Steam Oauth page
return sendRedirect(event, withQuery(config.authorizationURL as string, steamOpenIdParams))
}
const openIdCheck = {
ns: 'http://specs.openid.net/auth/2.0',
claimed_id: 'https://steamcommunity.com/openid/id/',
identity: 'https://steamcommunity.com/openid/id/',
}
const idRegex = /^https?:\/\/steamcommunity\.com\/openid\/id\/(\d+)$/
const steamIdCheck = idRegex.exec(query['openid.claimed_id'])
if (
query['openid.op_endpoint'] !== config.authorizationURL
|| !steamIdCheck
|| query['openid.ns'] !== openIdCheck.ns
|| !query['openid.claimed_id']?.startsWith(openIdCheck.claimed_id)
|| !query['openid.identity']?.startsWith(openIdCheck.identity)
) {
const error = createError({
statusCode: 401,
message: 'Steam login failed: Claimed identity is invalid.',
})
if (!onError) throw error
return onError(event, error)
}
const steamId = steamIdCheck[1]
// TODO: improve typing
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const user: any = await $fetch(withQuery('https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/', {
key: config.apiKey,
steamids: steamId,
}))
return onSuccess(event, {
user: user.response.players[0],
tokens: null,
})
})
}