passport-steam-openid 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,305 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SteamOpenIdStrategy = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const querystring_1 = tslib_1.__importDefault(require("querystring"));
6
+ const axios_1 = tslib_1.__importDefault(require("axios"));
7
+ const passport_1 = require("passport");
8
+ const error_1 = require("./error");
9
+ const constant_1 = require("./constant");
10
+ const type_1 = require("./type");
11
+ /**
12
+ * Strategy that authenticates you via steam openid without the use of any external openid libraries,
13
+ * which can and are source of many vulnerabilities.
14
+ *
15
+ * Functionality should be similar to `passport-steam`.
16
+ *
17
+ * @class SteamOpenIdStrategy
18
+ */
19
+ class SteamOpenIdStrategy extends passport_1.Strategy {
20
+ /**
21
+ * @constructor
22
+ *
23
+ * @param options.returnURL where steam redirects after parameters are passed
24
+ * @param options.profile if set, we will fetch user's profile from steam api
25
+ * @param options.apiKey api key to fetch user profile, not used if profile is false
26
+ * @param verify optional callback, called when user is successfully authenticated
27
+ */
28
+ constructor(options, verify) {
29
+ super();
30
+ this.name = 'steam-openid';
31
+ this.axios = axios_1.default.create();
32
+ this.returnURL = options.returnURL;
33
+ this.profile = options.profile;
34
+ if (options.profile)
35
+ this.apiKey = options.apiKey;
36
+ if (verify)
37
+ this.verify = verify;
38
+ }
39
+ /**
40
+ * Passport handle for authentication. We handle the query, passport does rest.
41
+ *
42
+ * @param req Base IncommingMessage request enhanced with parsed querystring.
43
+ */
44
+ authenticate(req) {
45
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
46
+ try {
47
+ const user = yield this.handleRequest(req);
48
+ if (!this.verify) {
49
+ this.success(user);
50
+ return;
51
+ }
52
+ this.verify(req, user.steamid, user, (err, user) => {
53
+ if (err) {
54
+ this.error(err);
55
+ return;
56
+ }
57
+ if (!user) {
58
+ this.error(new Error('No user was received from callback.'));
59
+ return;
60
+ }
61
+ this.success(user);
62
+ });
63
+ }
64
+ catch (err) {
65
+ if (this.isRetryableError(err)) {
66
+ this.redirect(this.buildRedirectUrl());
67
+ return;
68
+ }
69
+ this.error(err);
70
+ }
71
+ });
72
+ }
73
+ /**
74
+ * Handles validation request.
75
+ *
76
+ * Can be used in a middleware, if you don't like passport.
77
+ *
78
+ * @param req Base IncommingMessage request enhanced with parsed querystring.
79
+ * @returns
80
+ * @throws {SteamOpenIdError} User related problem, such as:
81
+ * - open.mode was not correct
82
+ * - query did not was pass validation
83
+ * - steam rejected this query
84
+ * - steamid is invalid
85
+ * @throws {Error} Non-recoverable errors, such as query object missing.
86
+ */
87
+ handleRequest(req) {
88
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
89
+ const query = this.getQuery(req);
90
+ if (!this.hasAuthQuery(query)) {
91
+ throw new error_1.SteamOpenIdError('openid.mode is incorrect.', type_1.SteamOpenIdErrorType.InvalidMode);
92
+ }
93
+ if (!this.isQueryValid(query)) {
94
+ throw new error_1.SteamOpenIdError('Supplied query is invalid.', type_1.SteamOpenIdErrorType.InvalidQuery);
95
+ }
96
+ // TODO: validate nonce time
97
+ const valid = yield this.validateAgainstSteam(query);
98
+ if (!valid) {
99
+ throw new error_1.SteamOpenIdError('Failed to validate query against steam.', type_1.SteamOpenIdErrorType.Unauthorized);
100
+ }
101
+ const steamId = this.getSteamId(query);
102
+ return yield this.getUser(steamId);
103
+ });
104
+ }
105
+ /**
106
+ * Checks if error is retryable,
107
+ * meaning user gets redirected to steam openid page.
108
+ *
109
+ * @param err from catch clause
110
+ * @returns true, if error should be retried
111
+ * @returns false, if error is not retriable
112
+ * and should be handled by the app.
113
+ */
114
+ isRetryableError(err) {
115
+ return (err instanceof error_1.SteamOpenIdError &&
116
+ err.code == type_1.SteamOpenIdErrorType.InvalidMode);
117
+ }
118
+ /**
119
+ * Retrieves query parameter from req object and checks if it is an object.
120
+ *
121
+ * @param req Base IncommingMessage request enhanced with parsed querystring.
122
+ * @returns query from said request
123
+ * @throws Error if query cannot be found, non-recoverable error.
124
+ */
125
+ getQuery(req) {
126
+ if (!req['query'] || typeof req['query'] != 'object') {
127
+ throw new Error('Query was not found on request object.');
128
+ }
129
+ return req['query'];
130
+ }
131
+ /**
132
+ * Checks if `mode` field from query is correct and thus authentication can begin
133
+ *
134
+ * @param query original query user submitted
135
+ * @returns true, if mode is correct, equal to `id_res`
136
+ * @returns false, if mode is incorrect
137
+ */
138
+ hasAuthQuery(query) {
139
+ return !!query['openid.mode'] && query['openid.mode'] == 'id_res';
140
+ }
141
+ /**
142
+ * Builds a redirect url for user that is about to authenticate
143
+ *
144
+ * @returns redirect url built with proper parameters
145
+ */
146
+ buildRedirectUrl() {
147
+ const openIdParams = {
148
+ 'openid.mode': 'checkid_setup',
149
+ 'openid.ns': constant_1.VALID_NONCE,
150
+ 'openid.identity': constant_1.VALID_ID_SELECT,
151
+ 'openid.claimed_id': constant_1.VALID_ID_SELECT,
152
+ 'openid.return_to': this.returnURL,
153
+ };
154
+ return `${constant_1.VALID_OPENID_ENDPOINT}?${querystring_1.default.stringify(openIdParams)}`;
155
+ }
156
+ /**
157
+ * Validates user submitted query, if it contains correct parameters.
158
+ * No excess parameters can be used.
159
+ *
160
+ * @param query original query user submitted
161
+ * @returns true, query contains correct parameters
162
+ * @returns false, query contains incorrect parameters
163
+ */
164
+ isQueryValid(query) {
165
+ for (const key of constant_1.OPENID_QUERY_PROPS) {
166
+ if (!query[key]) {
167
+ return false;
168
+ }
169
+ }
170
+ if (query['openid.ns'] != constant_1.VALID_NONCE)
171
+ return false;
172
+ if (query['openid.op_endpoint'] != constant_1.VALID_OPENID_ENDPOINT)
173
+ return false;
174
+ if (query['openid.claimed_id'] !== query['openid.identity'])
175
+ return false;
176
+ if (!this.isValidIdentity(query['openid.claimed_id']))
177
+ return false;
178
+ return query['openid.return_to'] == this.returnURL;
179
+ }
180
+ /**
181
+ * Checks if identity starts with correct link.
182
+ *
183
+ * @param identity from querystring
184
+ * @returns true, if identity is a string and starts with correct endpoint
185
+ * @return false, if above criteria was violated
186
+ */
187
+ isValidIdentity(identity) {
188
+ return (typeof identity == 'string' &&
189
+ !!identity.match(/^https:\/\/steamcommunity\.com\/openid\/id\/(7656119[0-9]{10})\/?$/));
190
+ }
191
+ /**
192
+ * Query trusted steam endpoint to validate supplied query.
193
+ *
194
+ * @param query original query user submitted
195
+ * @returns true, if positive response was received
196
+ * @returns false, if request failed, status is incorrect or data signals invalid
197
+ */
198
+ validateAgainstSteam(query) {
199
+ return this.axios
200
+ .post(constant_1.VALID_OPENID_ENDPOINT, this.getOpenIdValidationRequestBody(query), {
201
+ maxRedirects: 0,
202
+ headers: {
203
+ 'Content-Type': 'application/x-www-form-urlencoded',
204
+ },
205
+ })
206
+ .then(({ data, status }) => {
207
+ if (status !== 200) {
208
+ return false;
209
+ }
210
+ return this.isSteamResponseValid(data);
211
+ })
212
+ .catch(() => {
213
+ return false;
214
+ });
215
+ }
216
+ /**
217
+ * Clones query from authentication request, changes mode and stringifies to form data.
218
+ * @param query original query user submitted
219
+ * @returns stringified form data with changed mode
220
+ */
221
+ getOpenIdValidationRequestBody(query) {
222
+ const data = Object.assign({}, query);
223
+ data['openid.mode'] = 'check_authentication';
224
+ return querystring_1.default.stringify(data);
225
+ }
226
+ /**
227
+ * Validates response from steam to see if query is correct.
228
+ *
229
+ * @param response response received from steama
230
+ * @returns true, if data was in correct format and signals valid query
231
+ * @return false, if data was corrupted or invalid query was signaled
232
+ */
233
+ isSteamResponseValid(response) {
234
+ if (typeof response != 'string')
235
+ return false;
236
+ const match = response.match(/^ns:(.+)\nis_valid:(.+)\n$/);
237
+ if (!match)
238
+ return false;
239
+ if (match[1] != constant_1.VALID_NONCE)
240
+ return false;
241
+ return match[2] == 'true';
242
+ }
243
+ /**
244
+ * Parses steamId from `claimed_id` field, which is what openid 2.0 uses.
245
+ *
246
+ * @param query original query user submitted
247
+ * @returns parsed steamId
248
+ */
249
+ getSteamId(query) {
250
+ return query['openid.claimed_id']
251
+ .replace(`${constant_1.VALID_IDENTITY_ENDPOINT}/`, '')
252
+ .replace('/', ''); // Incase steam starts sending links ending with /
253
+ }
254
+ /**
255
+ * Abstract method for getting user that has been authenticated.
256
+ * You can implement fetching user from steamid and thus validating even more,
257
+ * or if you are satisified with just steamId, you can return it as an object
258
+ * and continue without need of an steam api key.
259
+ *
260
+ * @param steamId steamId parsed from `claimed_id`
261
+ * @return generic that was chosen by child class
262
+ */
263
+ getUser(steamId) {
264
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
265
+ // Kind of hacky way to force the generic, but will do for now.
266
+ if (this.profile) {
267
+ return this.fetchPlayerSummary(steamId);
268
+ }
269
+ return { steamid: steamId };
270
+ });
271
+ }
272
+ /**
273
+ * Fetches profile data for authenticated user.
274
+ * Validates the steamId even more.
275
+ *
276
+ * @param steamId parsed steamId from `claimed_id`
277
+ * @returns profile belonging to said steamId
278
+ *
279
+ * @throws {Error} if malformed response was received
280
+ * @throws {AxiosError} if status was not 200
281
+ * @throws {SteamOpenIdError} if profile was not found
282
+ */
283
+ fetchPlayerSummary(steamId) {
284
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
285
+ const summaryQuery = {
286
+ steamids: steamId,
287
+ key: this.apiKey,
288
+ };
289
+ return axios_1.default
290
+ .get(`${constant_1.PLAYER_SUMMARY_URL}/?${querystring_1.default.stringify(summaryQuery)}`)
291
+ .then(({ data }) => {
292
+ var _a;
293
+ if (!Array.isArray((_a = data === null || data === void 0 ? void 0 : data.response) === null || _a === void 0 ? void 0 : _a.players)) {
294
+ throw new Error('Malformed response from steam.');
295
+ }
296
+ const user = data.response.players[0];
297
+ if (!user) {
298
+ throw new error_1.SteamOpenIdError('Profile was not found on steam.', type_1.SteamOpenIdErrorType.InvalidSteamId);
299
+ }
300
+ return user;
301
+ });
302
+ });
303
+ }
304
+ }
305
+ exports.SteamOpenIdStrategy = SteamOpenIdStrategy;
package/dist/type.d.ts ADDED
@@ -0,0 +1,85 @@
1
+ import { DoneCallback } from 'passport';
2
+ export type BaseSteamOpenIdStrategyOptions = {
3
+ returnURL: string;
4
+ };
5
+ export type SteamOpenIdStrategyOptionsWithProfile = {
6
+ profile: true;
7
+ apiKey: string;
8
+ } & BaseSteamOpenIdStrategyOptions;
9
+ export type SteamOpenIdStrategyOptionsWithoutProfile = {
10
+ profile: false;
11
+ } & BaseSteamOpenIdStrategyOptions;
12
+ export type SteamOpenIdStrategyOptions = SteamOpenIdStrategyOptionsWithProfile | SteamOpenIdStrategyOptionsWithoutProfile;
13
+ /**
14
+ * Enum used to distinguish between user-related errors.
15
+ *
16
+ * @enum SteamOpenIdErrorType
17
+ */
18
+ export declare enum SteamOpenIdErrorType {
19
+ /**
20
+ * Invalid mode for authentication, should trigger redirect.
21
+ */
22
+ InvalidMode = 0,
23
+ /**
24
+ * Query has a wrong parameter or has excess parameters.
25
+ */
26
+ InvalidQuery = 1,
27
+ /**
28
+ * Steam rejected our query.
29
+ */
30
+ Unauthorized = 2,
31
+ /**
32
+ * SteamId is not valid.
33
+ */
34
+ InvalidSteamId = 3
35
+ }
36
+ /** When profile is not used, we just send a steamid. */
37
+ export type SteamOpenIdUser = {
38
+ steamid: string;
39
+ };
40
+ /** Api response for profile */
41
+ export type SteamPlayerSummaryResponse = {
42
+ response: {
43
+ players: SteamOpenIdUserProfile[];
44
+ };
45
+ };
46
+ /**
47
+ * Steam Player Summary
48
+ */
49
+ export type SteamOpenIdUserProfile = {
50
+ steamid: string;
51
+ communityvisibilitystate: number;
52
+ profilestate: number;
53
+ personaname: string;
54
+ commentpermission: number;
55
+ profileurl: string;
56
+ avatar: string;
57
+ avatarmedium: string;
58
+ avatarfull: string;
59
+ avatarhash: string;
60
+ lastlogoff: number;
61
+ personastate: number;
62
+ realname: string;
63
+ primaryclanid: string;
64
+ timecreated: number;
65
+ personastateflags: number;
66
+ loccountrycode: string;
67
+ locstatecode: string;
68
+ };
69
+ /**
70
+ * Optional callback inserted into the constructor of SteamOpenIdStrategy.
71
+ */
72
+ export type VerifyCallback<TUser extends SteamOpenIdUser | SteamOpenIdUserProfile> = (req: any, identifier: string, profile: TUser, done: DoneCallback) => any;
73
+ export type SteamOpenIdQuery = {
74
+ 'openid.ns': string;
75
+ 'openid.mode': string;
76
+ 'openid.op_endpoint': string;
77
+ 'openid.claimed_id': string;
78
+ 'openid.identity': string;
79
+ 'openid.return_to': string;
80
+ 'openid.response_nonce': string;
81
+ 'openid.assoc_handle': string;
82
+ 'openid.signed': string;
83
+ 'openid.sig': string;
84
+ };
85
+ //# sourceMappingURL=type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,MAAM,8BAA8B,GAAG;IAC3C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG;IAClD,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,8BAA8B,CAAC;AAEnC,MAAM,MAAM,wCAAwC,GAAG;IACrD,OAAO,EAAE,KAAK,CAAC;CAChB,GAAG,8BAA8B,CAAC;AAEnC,MAAM,MAAM,0BAA0B,GAClC,qCAAqC,GACrC,wCAAwC,CAAC;AAE7C;;;;GAIG;AACH,oBAAY,oBAAoB;IAC9B;;OAEG;IACH,WAAW,IAAI;IACf;;OAEG;IACH,YAAY,IAAI;IAChB;;OAEG;IACH,YAAY,IAAI;IAChB;;OAEG;IACH,cAAc,IAAI;CACnB;AAED,wDAAwD;AACxD,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,+BAA+B;AAC/B,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE;QACR,OAAO,EAAE,sBAAsB,EAAE,CAAC;KACnC,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB,EAAE,MAAM,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,CACxB,KAAK,SAAS,eAAe,GAAG,sBAAsB,IACpD,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,KAAK,GAAG,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uBAAuB,EAAE,MAAM,CAAC;IAChC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC"}
package/dist/type.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SteamOpenIdErrorType = void 0;
4
+ /**
5
+ * Enum used to distinguish between user-related errors.
6
+ *
7
+ * @enum SteamOpenIdErrorType
8
+ */
9
+ var SteamOpenIdErrorType;
10
+ (function (SteamOpenIdErrorType) {
11
+ /**
12
+ * Invalid mode for authentication, should trigger redirect.
13
+ */
14
+ SteamOpenIdErrorType[SteamOpenIdErrorType["InvalidMode"] = 0] = "InvalidMode";
15
+ /**
16
+ * Query has a wrong parameter or has excess parameters.
17
+ */
18
+ SteamOpenIdErrorType[SteamOpenIdErrorType["InvalidQuery"] = 1] = "InvalidQuery";
19
+ /**
20
+ * Steam rejected our query.
21
+ */
22
+ SteamOpenIdErrorType[SteamOpenIdErrorType["Unauthorized"] = 2] = "Unauthorized";
23
+ /**
24
+ * SteamId is not valid.
25
+ */
26
+ SteamOpenIdErrorType[SteamOpenIdErrorType["InvalidSteamId"] = 3] = "InvalidSteamId";
27
+ })(SteamOpenIdErrorType || (exports.SteamOpenIdErrorType = SteamOpenIdErrorType = {}));
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "passport-steam-openid",
3
+ "version": "1.0.0",
4
+ "description": "Passport strategy for authenticating with steam openid without the use of 3rd party openid packages.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "npx tsc",
9
+ "format": "npx prettier --write \"src/**/*.ts\"",
10
+ "lint": "npx eslint \"{src,test}/**/*.ts\" --fix",
11
+ "test": "echo \"Error: no test specified\" && exit 1",
12
+ "prepare": "npx husky install",
13
+ "semantic-release": "semantic-release"
14
+ },
15
+ "keywords": [],
16
+ "author": "glencoco",
17
+ "license": "MIT",
18
+ "dependencies": {
19
+ "axios": "^1.4.0",
20
+ "passport": "^0.6.0"
21
+ },
22
+ "devDependencies": {
23
+ "@semantic-release/changelog": "^6.0.3",
24
+ "@semantic-release/git": "^10.0.1",
25
+ "@types/node": "^20.3.1",
26
+ "@types/passport": "^1.0.12",
27
+ "@typescript-eslint/eslint-plugin": "^5.59.11",
28
+ "@typescript-eslint/parser": "^5.59.11",
29
+ "cz-conventional-changelog": "^3.3.0",
30
+ "eslint": "^8.43.0",
31
+ "eslint-config-prettier": "^8.8.0",
32
+ "eslint-plugin-prettier": "^4.2.1",
33
+ "eslint-plugin-sonarjs": "^0.19.0",
34
+ "husky": "^8.0.3",
35
+ "lint-staged": "^13.2.2",
36
+ "prettier": "^2.8.8",
37
+ "semantic-release": "^21.0.5",
38
+ "typescript": "^5.1.3"
39
+ },
40
+ "config": {
41
+ "commitizen": {
42
+ "path": "./node_modules/cz-conventional-changelog"
43
+ }
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/danocmx/passport-steam-openid.git"
48
+ }
49
+ }
@@ -0,0 +1,9 @@
1
+ module.exports = {
2
+ branches: ['master'],
3
+ plugins: [
4
+ '@semantic-release/commit-analyzer',
5
+ '@semantic-release/release-notes-generator',
6
+ '@semantic-release/npm',
7
+ '@semantic-release/git',
8
+ ],
9
+ };
@@ -0,0 +1,3 @@
1
+ NODE_ENV="development"
2
+ URL_BASE="http://example.com"
3
+ COOKIE_SECRET="secret"
@@ -0,0 +1,24 @@
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser',
3
+ parserOptions: {
4
+ sourceType: 'module',
5
+ },
6
+ plugins: ['@typescript-eslint/eslint-plugin', 'sonarjs'],
7
+ extends: [
8
+ 'plugin:@typescript-eslint/recommended',
9
+ 'plugin:prettier/recommended',
10
+ 'plugin:sonarjs/recommended',
11
+ ],
12
+ root: true,
13
+ env: {
14
+ node: true,
15
+ jest: true,
16
+ },
17
+ ignorePatterns: ['.eslintrc.js'],
18
+ rules: {
19
+ '@typescript-eslint/interface-name-prefix': 'off',
20
+ '@typescript-eslint/explicit-function-return-type': 'off',
21
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
22
+ '@typescript-eslint/no-explicit-any': 'off',
23
+ },
24
+ };
@@ -0,0 +1,4 @@
1
+ {
2
+ "singleQuote": true,
3
+ "trailingComma": "all"
4
+ }
@@ -0,0 +1,23 @@
1
+ # passport-steam-openid sample
2
+ Sample application to demonstate usage of `passport-steam-openid` in express.js enviroment.
3
+
4
+ ## Environment
5
+ Set these variables in your `.env` file:
6
+ - `NODE_ENV` - `production` or `development`.
7
+ - `URL_BASE` - url used for return URL in `production` environment.
8
+ - `COOKIE_SECRET` - used for encrypting sessions
9
+
10
+ ## Dependencies
11
+ Install via npm:
12
+ ```
13
+ npm install
14
+ ```
15
+ After installing this application.
16
+
17
+ ## Compilation and running
18
+ You can use package.json scripts:
19
+ - `npm run build` for building with typescript
20
+ - `npm start` for starting app on port 3000
21
+
22
+ ## License
23
+ This sample is released under MIT license.