1
1
import { mf2 } from "microformats-parser" ;
2
2
3
3
/**
4
- * Get client information
5
- * @param {string } client_id - Client URL
6
- * @returns {Promise<object> } Information about the client
7
- * @see {@link https://indieauth.spec.indieweb.org/#client-information-discovery }
4
+ * Get client information from application Microformat
5
+ * @param {string } body - Response body
6
+ * @param {object } client - Fallback client information
7
+ * @returns {object } Client information
8
+ * @deprecated since 11 July 2024
9
+ * @see {@link https://indieauth.spec.indieweb.org/20220212/#application-information }
8
10
*/
9
- export const getClientInformation = async ( client_id ) => {
10
- let client = {
11
- name : new URL ( client_id ) . host ,
12
- url : client_id ,
13
- } ;
14
-
15
- const clientResponse = await fetch ( client_id ) ;
16
- if ( ! clientResponse . ok ) {
17
- return client ;
18
- }
19
-
20
- const body = await clientResponse . text ( ) ;
21
-
22
- // If response contains microformats, use available derived values
23
- const { items } = mf2 ( body , { baseUrl : client_id } ) ;
11
+ export const getApplicationInformation = ( body , client ) => {
12
+ const { items } = mf2 ( body , { baseUrl : client . url } ) ;
24
13
for ( const item of items ) {
25
14
const { properties, type } = item ;
26
15
27
16
if ( / ^ h - (?: x - ) ? a p p $ / . test ( type [ 0 ] ) ) {
28
- // If no URL property, use `client_id`
17
+ // If no URL property, use baseUrl
29
18
if ( ! properties . url ) {
30
- properties . url = [ client_id ] ;
19
+ properties . url = [ client . url ] ;
31
20
}
32
21
33
- // If has URL property, only continue if matches `client_id`
34
- if ( ! properties . url ?. includes ( client_id ) ) {
22
+ // Check that URL property matches `client_id`. Note that this isn’t for
23
+ // authentication, but to ensure only relevant client metadata is returned
24
+ if ( ! properties . url ?. includes ( client . url ) ) {
35
25
continue ;
36
26
}
37
27
@@ -48,3 +38,56 @@ export const getClientInformation = async (client_id) => {
48
38
49
39
return client ;
50
40
} ;
41
+
42
+ /**
43
+ * Get client information from client metadata
44
+ * @param {string } body - Response body
45
+ * @param {object } client - Fallback client information
46
+ * @returns {object } Client information
47
+ * @see {@link https://indieauth.spec.indieweb.org/#client-metadata }
48
+ */
49
+ export const getClientMetadata = ( body , client ) => {
50
+ const json = JSON . parse ( body ) ;
51
+
52
+ // Client metadata MUST include `client_id`
53
+ if ( ! Object . hasOwn ( json , "client_id" ) ) {
54
+ throw new Error ( "Client metadata JSON not valid" ) ;
55
+ }
56
+
57
+ return {
58
+ ...client ,
59
+ logo : json . logo_uri ,
60
+ name : json . client_name || client . name ,
61
+ url : json . client_uri || client . url ,
62
+ } ;
63
+ } ;
64
+
65
+ /**
66
+ * Get client information
67
+ * @param {string } clientId - Client ID
68
+ * @returns {Promise<object> } Information about the client
69
+ * @see {@link https://indieauth.spec.indieweb.org/#client-information-discovery }
70
+ */
71
+ export const getClientInformation = async ( clientId ) => {
72
+ let client = {
73
+ id : clientId ,
74
+ name : new URL ( clientId ) . host ,
75
+ url : new URL ( clientId ) . href ,
76
+ } ;
77
+
78
+ const clientResponse = await fetch ( clientId ) ;
79
+ if ( ! clientResponse . ok ) {
80
+ // Use information derived from clientId
81
+ return client ;
82
+ }
83
+
84
+ const body = await clientResponse . text ( ) ;
85
+
86
+ try {
87
+ // Use information from client JSON metadata
88
+ return getClientMetadata ( body , client ) ;
89
+ } catch {
90
+ // Use information from client HTML microformats (deprecated)
91
+ return getApplicationInformation ( body , client ) ;
92
+ }
93
+ } ;
0 commit comments