Skip to content

Commit f2f15b4

Browse files
committed
feat(types): rename field to authParams
1 parent 02eb7ef commit f2f15b4

File tree

5 files changed

+62
-48
lines changed

5 files changed

+62
-48
lines changed

authorization.json

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
[
2-
{
3-
"name": "simple authorization header",
4-
"header": "basic",
5-
"expected": { "authScheme": "basic", "token": null }
6-
},
72
{
83
"name": "basic",
94
"ref": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization#basic_authentication",
105
"header": "Basic YWxhZGRpbjpvcGVuc2VzYW1l",
11-
"expected": { "authScheme": "Basic", "token": "YWxhZGRpbjpvcGVuc2VzYW1l" }
6+
"expected": {
7+
"authScheme": "Basic",
8+
"authParams": "YWxhZGRpbjpvcGVuc2VzYW1l"
9+
}
1210
},
1311
{
1412
"name": "bearer",
1513
"ref": "https://datatracker.ietf.org/doc/html/rfc6750#section-3",
1614
"header": "Bearer realm=\"example\", error=\"invalid_token\", error_description=\"The access token expired\"",
1715
"expected": {
1816
"authScheme": "Bearer",
19-
"token": {
17+
"authParams": {
2018
"realm": "\"example\"",
2119
"error": "\"invalid_token\"",
2220
"error_description": "\"The access token expired\""
@@ -26,54 +24,54 @@
2624
{
2725
"name": "digest",
2826
"ref": "https://datatracker.ietf.org/doc/html/rfc7616#section-3.9.1",
29-
"header": "Digest username=\"Mufasa\",realm=\"[email protected]\",uri=\"/dir/index.html\",algorithm=SHA-256,nonce=\"7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v\",nc=00000001,cnonce=\"f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ\",qop=auth,response=\"753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1\",opaque=\"FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS\"",
27+
"header": "Digest username=\"Mufasa\", realm=\"[email protected]\", uri=\"/dir/index.html\", algorithm=SHA-256, nonce=\"7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v\", nc=00000001, cnonce=\"f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ\", qop=auth, response=\"753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1\", opaque=\"FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS\"",
3028
"expected": {
3129
"authScheme": "Digest",
32-
"token": {
30+
"authParams": {
31+
"username": "\"Mufasa\"",
32+
"realm": "\"[email protected]\"",
33+
"uri": "\"/dir/index.html\"",
3334
"algorithm": "SHA-256",
34-
"cnonce": "\"f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ\"",
35-
"nc": "00000001",
3635
"nonce": "\"7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v\"",
37-
"opaque": "\"FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS\"",
36+
"nc": "00000001",
37+
"cnonce": "\"f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ\"",
3838
"qop": "auth",
39-
"realm": "\"[email protected]\"",
4039
"response": "\"753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1\"",
41-
"uri": "\"/dir/index.html\"",
42-
"username": "\"Mufasa\""
40+
"opaque": "\"FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS\""
4341
}
4442
}
4543
},
4644
{
4745
"name": "Example with SHA-512-256, Charset, and Userhash",
48-
"header": "Digest username=\"488869477bf257147b804c45308cd62ac4e25eb717b12b298c79e62dcea254ec\",realm=\"[email protected]\",uri=\"/doe.json\",algorithm=SHA-512-256,nonce=\"5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK\",nc=00000001,cnonce=\"NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v\",qop=auth,response=\"ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d6c861229025f607a79dd\",opaque=\"HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS\",userhash=true",
46+
"header": "Digest username=\"488869477bf257147b804c45308cd62ac4e25eb717b12b298c79e62dcea254ec\", realm=\"[email protected]\", uri=\"/doe.json\", algorithm=SHA-512-256, nonce=\"5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK\", nc=00000001, cnonce=\"NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v\", qop=auth, response=\"ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d6c861229025f607a79dd\", opaque=\"HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS\", userhash=true",
4947
"ref": "https://datatracker.ietf.org/doc/html/rfc7616#section-3.9.2",
5048
"expected": {
5149
"authScheme": "Digest",
52-
"token": {
50+
"authParams": {
51+
"username": "\"488869477bf257147b804c45308cd62ac4e25eb717b12b298c79e62dcea254ec\"",
52+
"realm": "\"[email protected]\"",
53+
"uri": "\"/doe.json\"",
5354
"algorithm": "SHA-512-256",
54-
"cnonce": "\"NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v\"",
55-
"nc": "00000001",
5655
"nonce": "\"5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK\"",
57-
"opaque": "\"HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS\"",
56+
"nc": "00000001",
57+
"cnonce": "\"NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v\"",
5858
"qop": "auth",
59-
"realm": "\"[email protected]\"",
6059
"response": "\"ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d6c861229025f607a79dd\"",
61-
"uri": "\"/doe.json\"",
62-
"userhash": "true",
63-
"username": "\"488869477bf257147b804c45308cd62ac4e25eb717b12b298c79e62dcea254ec\""
60+
"opaque": "\"HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS\"",
61+
"userhash": "true"
6462
}
6563
}
6664
},
6765
{
6866
"name": "Example for AWS4-HMAC-SHA256",
69-
"header": "AWS4-HMAC-SHA256 Credential=\"AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request\", SignedHeaders=\"host;range;x-amz-date\",Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024",
67+
"header": "AWS4-HMAC-SHA256 Credential=\"AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request\", SignedHeaders=\"host;range;x-amz-date\", Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024",
7068
"ref": "https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html",
7169
"expected": {
7270
"authScheme": "AWS4-HMAC-SHA256",
73-
"token": {
71+
"authParams": {
7472
"Credential": "\"AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request\"",
75-
"Signature": "fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024",
76-
"SignedHeaders": "\"host;range;x-amz-date\""
73+
"SignedHeaders": "\"host;range;x-amz-date\"",
74+
"Signature": "fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024"
7775
}
7876
}
7977
},

constants.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright 2023-latest the httpland authors. All rights reserved. MIT license.
2+
// This module is browser compatible.
3+
4+
export const enum Msg {
5+
InvalidSyntax = "unexpected Authorization input",
6+
DuplicatedKeys = "auth param keys should be case insensitive unique",
7+
InvalidToken = "should be <token> format",
8+
InvalidToken68 = "should be <token68> format",
9+
}

parse.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@
22
// This module is browser compatible.
33

44
import { duplicate, parseList } from "./utils.ts";
5-
import { head, toLowerCase } from "./deps.ts";
6-
import type { Authorization, AuthParam } from "./types.ts";
7-
8-
const enum Msg {
9-
InvalidSyntax = "unexpected Authorization input",
10-
DuplicatedKeys = "auth param keys should be case insensitive unique",
11-
}
5+
import { head, isString, toLowerCase } from "./deps.ts";
6+
import { Msg } from "./constants.ts";
7+
import type { Authorization, AuthParams } from "./types.ts";
128

139
const reAuthorization =
1410
/^(?<authScheme>[!#$%&'*+.^_`|~\dA-Za-z-]+)(?: +(?:(?<token68>(?:[A-Za-z]|\d|[-._~+/])+=*)|(?<authParam>.+)))?$/;
@@ -46,19 +42,28 @@ export function parseAuthorization(input: string): Authorization {
4642

4743
if (!result || !result.groups) throw SyntaxError(Msg.InvalidSyntax);
4844

49-
const { authScheme, token68, authParam: authParamStr } = result.groups;
50-
const token = authParamStr ? parseAuthParam(authParamStr) : token68 ?? null;
45+
const groups = result.groups as ParsedGroups;
46+
const { authScheme } = groups;
47+
const authParams = isString(groups.authParam)
48+
? parseAuthParams(groups.authParam)
49+
: groups.token68;
5150

52-
return { authScheme: authScheme!, token };
51+
return { authScheme, authParams: authParams ?? null };
5352
}
5453

54+
type ParsedGroups = {
55+
readonly authScheme: string;
56+
readonly token68: string | undefined;
57+
readonly authParam: string | undefined;
58+
};
59+
5560
const reAuthParam =
5661
/^(?<key>[!#$%&'*+.^_`|~\dA-Za-z-]+)[ \t]*=[ \t]*(?<value>[!#$%&'*+.^_`|~\dA-Za-z-]+|"(?:\t| |!|[\x23-\x5B/, /[\x5D-\x7E]|[\x80-\xFF]|\\(?:\t| |[\x21-\x7E])[\x80-\xFF])*")$/;
5762

5863
/** Parse string into {@link AuthParam}.
5964
* @throws {Error} If the auth param key is duplicated.
6065
*/
61-
export function parseAuthParam(input: string): AuthParam {
66+
export function parseAuthParams(input: string): AuthParams {
6267
const list = parseList(input);
6368

6469
const entries = list.map((el) => {

parse_test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { parseAuthorization, parseAuthParam } from "./parse.ts";
1+
import { parseAuthorization, parseAuthParams } from "./parse.ts";
22
import {
33
assertEquals,
44
assertIsError,
@@ -49,14 +49,14 @@ describe("parseAuthorization", () => {
4949
});
5050
});
5151

52-
describe("parseAuthParam", () => {
52+
describe("parseAuthParams", () => {
5353
authParam.forEach((v) => {
5454
it(v.name, () => {
5555
if (v.must_fail) {
56-
assertThrows(() => parseAuthParam(v.header));
56+
assertThrows(() => parseAuthParams(v.header));
5757
} else {
5858
assertEquals<Record<string, unknown>>(
59-
parseAuthParam(v.header),
59+
parseAuthParams(v.header),
6060
v.expected!,
6161
);
6262
}

types.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// Copyright 2023-latest the httpland authors. All rights reserved. MIT license.
22
// This module is browser compatible.
33

4-
/** Authorization API. */
5-
export interface Authorization {
4+
/** Credentials API. */
5+
export interface Credentials {
66
/** Authentication scheme. */
77
readonly authScheme: string;
88

9-
/** token68 or auth-param. */
10-
readonly token: Token68 | AuthParam | null;
9+
/** Authentication parameters. */
10+
readonly authParams: Token68 | AuthParams | null;
1111
}
1212

1313
/** Representation of [token68](https://www.rfc-editor.org/rfc/rfc9110.html#auth.params). */
@@ -16,6 +16,8 @@ export type Token68 = string;
1616
/** Pair of name and value.
1717
* Representation of [auth-param](https://www.rfc-editor.org/rfc/rfc9110.html#section-11.2-5).
1818
*/
19-
export interface AuthParam {
19+
export interface AuthParams {
2020
readonly [k: string]: string;
2121
}
22+
23+
export type Authorization = Credentials;

0 commit comments

Comments
 (0)