error in rfc6750
This commit is contained in:
		| @@ -167,8 +167,16 @@ function getQueryMode(issuerUrl: string): oauth2orize.grant.Options['modes'] { | |||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Maps the transaction ID and the oauth/authorize parameters. | ||||||
|  |  * | ||||||
|  |  * Flow: | ||||||
|  |  * 1. oauth/authorize endpoint will call store() to store the parameters | ||||||
|  |  *    and puts the generated transaction ID to the dialog page | ||||||
|  |  * 2. oauth/decision will call load() to retrieve the parameters and then remove() | ||||||
|  |  */ | ||||||
| class OAuth2Store { | class OAuth2Store { | ||||||
| 	#cache = new MemoryKVCache<OAuth2>(1000 * 60 * 5); // 5min | 	#cache = new MemoryKVCache<OAuth2>(1000 * 60 * 5); // expires after 5min | ||||||
|  |  | ||||||
| 	load(req: OAuth2DecisionRequest, cb: (err: Error | null, txn?: OAuth2) => void): void { | 	load(req: OAuth2DecisionRequest, cb: (err: Error | null, txn?: OAuth2) => void): void { | ||||||
| 		const { transaction_id } = req.body; | 		const { transaction_id } = req.body; | ||||||
| @@ -178,7 +186,7 @@ class OAuth2Store { | |||||||
| 		} | 		} | ||||||
| 		const loaded = this.#cache.get(transaction_id); | 		const loaded = this.#cache.get(transaction_id); | ||||||
| 		if (!loaded) { | 		if (!loaded) { | ||||||
| 			cb(new AuthorizationError('Failed to load transaction', 'access_denied')); | 			cb(new AuthorizationError('Invalid or expired transaction ID', 'access_denied')); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		cb(null, loaded); | 		cb(null, loaded); | ||||||
| @@ -217,7 +225,6 @@ export class OAuth2ProviderService { | |||||||
| 	) { | 	) { | ||||||
| 		this.#logger = loggerService.getLogger('oauth'); | 		this.#logger = loggerService.getLogger('oauth'); | ||||||
|  |  | ||||||
| 		// XXX: But MemoryKVCache just grows forever without being cleared if grant codes are left unused |  | ||||||
| 		const grantCodeCache = new MemoryKVCache<{ | 		const grantCodeCache = new MemoryKVCache<{ | ||||||
| 			clientId: string, | 			clientId: string, | ||||||
| 			userId: string, | 			userId: string, | ||||||
| @@ -229,7 +236,7 @@ export class OAuth2ProviderService { | |||||||
| 			grantedToken?: string, | 			grantedToken?: string, | ||||||
| 			revoked?: boolean, | 			revoked?: boolean, | ||||||
| 			used?: boolean, | 			used?: boolean, | ||||||
| 		}>(1000 * 60 * 5); // 5m | 		}>(1000 * 60 * 5); // expires after 5m | ||||||
|  |  | ||||||
| 		// https://datatracker.ietf.org/doc/html/rfc7636.html | 		// https://datatracker.ietf.org/doc/html/rfc7636.html | ||||||
| 		this.#server.grant(oauth2Pkce.extensions()); | 		this.#server.grant(oauth2Pkce.extensions()); | ||||||
| @@ -238,7 +245,7 @@ export class OAuth2ProviderService { | |||||||
| 		}, (client, redirectUri, token, ares, areq, locals, done) => { | 		}, (client, redirectUri, token, ares, areq, locals, done) => { | ||||||
| 			(async (): Promise<OmitFirstElement<Parameters<typeof done>>> => { | 			(async (): Promise<OmitFirstElement<Parameters<typeof done>>> => { | ||||||
| 				this.#logger.info(`Checking the user before sending authorization code to ${client.id}`); | 				this.#logger.info(`Checking the user before sending authorization code to ${client.id}`); | ||||||
| 				const code = secureRndstr(32, true); | 				const code = secureRndstr(128, true); | ||||||
|  |  | ||||||
| 				if (!token) { | 				if (!token) { | ||||||
| 					throw new AuthorizationError('No user', 'invalid_request'); | 					throw new AuthorizationError('No user', 'invalid_request'); | ||||||
|   | |||||||
| @@ -471,7 +471,7 @@ describe('OAuth', () => { | |||||||
| 				}, | 				}, | ||||||
| 				body: JSON.stringify({ text: 'test' }), | 				body: JSON.stringify({ text: 'test' }), | ||||||
| 			}); | 			}); | ||||||
| 			assert.strictEqual(createResponse2.status, 403); | 			assert.strictEqual(createResponse2.status, 401); | ||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| @@ -659,10 +659,7 @@ describe('OAuth', () => { | |||||||
| 		// "The access token provided is expired, revoked, malformed, or | 		// "The access token provided is expired, revoked, malformed, or | ||||||
| 		// invalid for other reasons.  The resource SHOULD respond with | 		// invalid for other reasons.  The resource SHOULD respond with | ||||||
| 		// the HTTP 401 (Unauthorized) status code." | 		// the HTTP 401 (Unauthorized) status code." | ||||||
| 		// (but it's SHOULD not MUST. 403 should be okay for now.) | 		await assertDirectError(createResponse as Response, 401, 'invalid_token'); | ||||||
| 		assert.strictEqual(createResponse.status, 403); |  | ||||||
|  |  | ||||||
| 		// TODO: error code (wrong Authorization header should emit OAuth error instead of Misskey API error) |  | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	// https://datatracker.ietf.org/doc/html/rfc6749.html#section-3.1.2.4 | 	// https://datatracker.ietf.org/doc/html/rfc6749.html#section-3.1.2.4 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Kagami Sascha Rosylight
					Kagami Sascha Rosylight