const dns = require('dns');
const common = require('./common');
const Enum = require('./enum');
+const { Microformat2: { Relation: MF2Rel } } = Enum;
const { ValidationError } = require('./errors');
const { fileScope } = require('@squeep/log-helper');
* call would already have failed.
*/
address = new Address6(urlObj.hostname.slice(1, urlObj.hostname.length - 1));
- /* succeeded parsing as ipv6, reject unless loopback */
+ /* Succeeded parsing as ipv6, reject unless loopback */
urlObj.isLoopback = address.isLoopback();
} else {
try {
address = new Address4(urlObj.hostname);
- /* succeeded parsing as ipv4, reject unless loopback */
+ /* Succeeded parsing as ipv4, reject unless loopback */
urlObj.isLoopback = address.isInSubnet(loopback4);
} catch (e) {
- /* did not parse as ip, carry on */
+ /* Did not parse as ip, carry on */
}
}
throw new ValidationError('could not resolve hostname');
}
- // extract each resolution value, array of {address,family}
+ // Extract each resolution value, array of {address,family}
const resolutions = settledResolutions.map((resolution) => resolution.value);
// If there were two resolutions, ensure they returned identical results.
if (resolutions.length > 1) {
- // create set of addresses for each resolution
+ // Create set of addresses for each resolution
const addressSets = resolutions.map((addrs) => {
return new Set((addrs || []).map((a) => a.address));
});
const _scope = _fileScope('validateProfile');
const errorScope = 'invalid profile url';
- const options = Object.assign({
+ const options = {
allowLoopback: false,
resolveHostname: false,
- }, validationOptions);
+ ...validationOptions,
+ };
let profile;
try {
const _scope = _fileScope('validateClientIdentifier');
const errorScope = 'invalid client identifier url';
- const options = Object.assign({
+ const options = {
allowLoopback: true,
resolveHostname: true,
- }, validationOptions);
+ ...validationOptions,
+ };
let clientId;
try {
* @returns {Promise<ClientIdentifierData|undefined>} mf2 data filtered for h-app items, or undefined if url could not be fetched
*/
async fetchClientIdentifier(urlObj) {
- const _scope = _fileScope('fetchClientIdentifier');
-
- // Loopback address will eschew client fetch, return empty data.
- const isLoopbackResult = {
- rels: {},
- items: [],
- };
-
// Set by validation method in case of loopback ip hostname
if (urlObj.isLoopback) {
- return isLoopbackResult;
+ // Loopback address will eschew client fetch, return empty data.
+ return {
+ rels: {},
+ items: [],
+ };
}
const mfData = await this.fetchMicroformat(urlObj);
metadata: {},
};
- // Locate h-card mf2 items with url field matching profile url,
- // and populate profile fields with first-encountered card values.
+ /**
+ * Locate h-card mf2 items with url field matching profile url,
+ * and populate profile fields with first-encountered card values.
+ */
if (mfData && 'items' in mfData) {
const hCards = mfData.items.filter((item) =>
item?.type?.includes('h-card') &&
- item.properties && item.properties.url && item.properties.url.includes(urlObj.href));
+ item?.properties?.url?.includes(urlObj.href));
hCards.forEach((hCard) => {
Object.keys(profile).forEach((key) => {
if (!profile[key] && key in hCard.properties) { // eslint-disable-line security/detect-object-injection
// Populate legacy mf2 fields from relation links.
// These will be overwritten if they also exist in server metadata.
Object.entries({
- authorizationEndpoint: 'authorization_endpoint', // backwards compatibility
- tokenEndpoint: 'token_endpoint', // backwards compatibility
- ticketEndpoint: 'ticket_endpoint', // backwards compatibility
+ authorizationEndpoint: MF2Rel.AuthorizationEndpoint, // Backwards compatibility
+ tokenEndpoint: MF2Rel.TokenEndpoint, // Backwards compatibility
+ ticketEndpoint: MF2Rel.TicketEndpoint, // Backwards compatibility
}).forEach(([p, r]) => {
if (mfData && r in mfData.rels) {
profile.metadata[p] = profile[p] = mfData.rels[r][0]; // eslint-disable-line security/detect-object-injection
});
// Set metadata field.
- if (mfData && 'indieauth-metadata' in mfData.rels) {
- profile.indieauthMetadata = mfData.rels['indieauth-metadata'][0];
+ if (mfData && MF2Rel.IndieauthMetadata in mfData.rels) {
+ profile.indieauthMetadata = mfData.rels[MF2Rel.IndieauthMetadata][0];
}
// Attempt to populate metadata from authorization server.
try {
const response = await this.got(postIntrospectConfig);
- // check status
+ // Check status
try {
const {
active,
let metadataUrl, tokenUrl;
if (urlObj) {
const mfData = await this.fetchMicroformat(urlObj);
- const metadataRel = mfData?.rels?.['indieauth-metadata']?.[0];
+ const metadataRel = mfData?.rels?.[MF2Rel.IndieauthMetadata]?.[0];
if (metadataRel) {
try {
metadataUrl = new URL(metadataRel);
}
}
if (!metadataUrl) {
- // no metadata rel, try old-style token endpoint
- const tokenRel = mfData?.rels?.['token_endpoint']?.[0];
+ // No metadata rel, try old-style token endpoint
+ const tokenRel = mfData?.rels?.[MF2Rel.TokenEndpoint]?.[0];
if (tokenRel) {
try {
tokenUrl = new URL(tokenRel);