-
Notifications
You must be signed in to change notification settings - Fork 10
/
index.js
128 lines (113 loc) · 3.74 KB
/
index.js
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Require Dependencies
const axios = require("axios");
const openid = require("openid");
const url = require("url");
const OPENID_CHECK = {
ns: 'http://specs.openid.net/auth/2.0',
op_endpoint: 'https://steamcommunity.com/openid/login',
claimed_id: 'https://steamcommunity.com/openid/id/',
identity: 'https://steamcommunity.com/openid/id/',
};
// Main Class
class SteamAuth {
constructor({ realm, returnUrl, apiKey }) {
if (!realm || !returnUrl || !apiKey)
throw new Error(
"Missing realm, returnURL or apiKey parameter(s). These are required."
);
this.realm = realm;
this.returnUrl = returnUrl;
this.apiKey = apiKey;
this.relyingParty = new openid.RelyingParty(
returnUrl,
realm,
true,
true,
[]
);
}
// Get redirect url for Steam
async getRedirectUrl() {
return new Promise((resolve, reject) => {
this.relyingParty.authenticate(
"https://steamcommunity.com/openid",
false,
(error, authUrl) => {
if (error) return reject("Authentication failed: " + error);
if (!authUrl) return reject("Authentication failed.");
resolve(authUrl);
}
);
});
}
// Fetch user
async fetchIdentifier(steamOpenId) {
return new Promise(async (resolve, reject) => {
// Parse steamid from the url
const steamId = steamOpenId.replace(
"https://steamcommunity.com/openid/id/",
""
);
try {
const response = await axios.get(
`https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${this.apiKey}&steamids=${steamId}`
);
const players =
response.data &&
response.data.response &&
response.data.response.players;
if (players && players.length > 0) {
// Get the player
const player = players[0];
// Return user data
resolve({
_json: player,
steamid: steamId,
username: player.personaname,
name: player.realname,
profile: player.profileurl,
avatar: {
small: player.avatar,
medium: player.avatarmedium,
large: player.avatarfull
}
});
} else {
reject("No players found for the given SteamID.");
}
} catch (error) {
reject("Steam server error: " + error.message);
}
});
}
// Authenticate user
async authenticate(req) {
return new Promise((resolve, reject) => {
const searchParams = url.parse(req.url, true).query;
if (searchParams['openid.ns'] !== OPENID_CHECK.ns) return reject("Claimed identity is not valid.");
if (searchParams['openid.op_endpoint'] !== OPENID_CHECK.op_endpoint) return reject("Claimed identity is not valid.");
if (!searchParams['openid.claimed_id']?.startsWith(OPENID_CHECK.claimed_id)) return reject("Claimed identity is not valid.");
if (!searchParams['openid.identity']?.startsWith(OPENID_CHECK.identity)) return reject("Claimed identity is not valid.");
// Verify assertion
this.relyingParty.verifyAssertion(req, async (error, result) => {
if (error) return reject(error.message);
if (!result || !result.authenticated)
return reject("Failed to authenticate user.");
if (
!/^https?:\/\/steamcommunity\.com\/openid\/id\/\d+$/.test(
result.claimedIdentifier
)
)
return reject("Claimed identity is not valid.");
try {
const user = await this.fetchIdentifier(result.claimedIdentifier);
return resolve(user);
} catch (error) {
reject(error);
}
});
});
}
}
// Export class
module.exports = SteamAuth;