@sphereon/oid4vci-common
Version:
OpenID 4 Verifiable Credential Issuance Common Types
147 lines • 7.31 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.adjustUrl = exports.trimStart = exports.trimEnd = exports.trimBoth = exports.isValidURL = exports.post = exports.formPost = exports.getJson = void 0;
const cross_fetch_1 = require("cross-fetch");
const debug_1 = __importDefault(require("debug"));
const types_1 = require("../types");
const debug = (0, debug_1.default)('sphereon:openid4vci:http');
const getJson = (URL, opts) => __awaiter(void 0, void 0, void 0, function* () {
return yield openIdFetch(URL, undefined, Object.assign({ method: 'GET' }, opts));
});
exports.getJson = getJson;
const formPost = (url, body, opts) => __awaiter(void 0, void 0, void 0, function* () {
return yield (0, exports.post)(url, body, (opts === null || opts === void 0 ? void 0 : opts.contentType) ? Object.assign({}, opts) : Object.assign({ contentType: types_1.Encoding.FORM_URL_ENCODED }, opts));
});
exports.formPost = formPost;
const post = (url, body, opts) => __awaiter(void 0, void 0, void 0, function* () {
return yield openIdFetch(url, body, Object.assign({ method: 'POST' }, opts));
});
exports.post = post;
const openIdFetch = (url, body, opts) => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const headers = (_a = opts === null || opts === void 0 ? void 0 : opts.customHeaders) !== null && _a !== void 0 ? _a : {};
if (opts === null || opts === void 0 ? void 0 : opts.bearerToken) {
headers['Authorization'] =
`${headers.dpop ? 'DPoP' : 'Bearer'} ${typeof opts.bearerToken === 'function' ? yield opts.bearerToken() : opts.bearerToken}`;
}
const method = (opts === null || opts === void 0 ? void 0 : opts.method) ? opts.method : body ? 'POST' : 'GET';
const accept = (opts === null || opts === void 0 ? void 0 : opts.accept) ? opts.accept : 'application/json';
headers['Accept'] = accept;
if (headers['Content-Type']) {
if ((opts === null || opts === void 0 ? void 0 : opts.contentType) && opts.contentType !== headers['Content-Type']) {
throw Error(`Mismatch in content-types from custom headers (${headers['Content-Type']}) and supplied content type option (${opts.contentType})`);
}
}
else {
if (opts === null || opts === void 0 ? void 0 : opts.contentType) {
headers['Content-Type'] = opts.contentType;
}
else if (method !== 'GET') {
headers['Content-Type'] = 'application/json';
}
}
const payload = {
method,
headers,
body,
};
debug(`START fetching url: ${url}`);
if (body) {
debug(`Body:\r\n${typeof body == 'string' ? body : JSON.stringify(body)}`);
}
debug(`Headers:\r\n${JSON.stringify(payload.headers)}`);
const origResponse = yield (0, cross_fetch_1.fetch)(url, payload);
const isJSONResponse = accept === 'application/json' || origResponse.headers.get('Content-Type') === 'application/json';
const success = origResponse && origResponse.status >= 200 && origResponse.status < 400;
const responseText = yield origResponse.text();
const responseBody = isJSONResponse && responseText.includes('{') ? JSON.parse(responseText) : responseText;
debug(`${success ? 'success' : 'error'} status: ${origResponse.status}, body:\r\n${JSON.stringify(responseBody)}`);
if (!success && (opts === null || opts === void 0 ? void 0 : opts.exceptionOnHttpErrorStatus)) {
const error = JSON.stringify(responseBody);
throw new Error(error === '{}' ? '{"error": "not found"}' : error);
}
debug(`END fetching url: ${url}`);
return {
origResponse,
successBody: success ? responseBody : undefined,
errorBody: !success ? responseBody : undefined,
};
});
const isValidURL = (url) => {
const urlPattern = new RegExp('^(https?:\\/\\/)' + // validate protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // validate domain name
'((localhost))|' + // validate OR localhost
'((\\d{1,3}\\.){3}\\d{1,3}))' + // validate OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+:]*)*' + // validate port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // validate query string
'(\\#[-a-z\\d_]*)?$', // validate fragment locator
'i');
return urlPattern.test(url);
};
exports.isValidURL = isValidURL;
const trimBoth = (value, trim) => {
return (0, exports.trimEnd)((0, exports.trimStart)(value, trim), trim);
};
exports.trimBoth = trimBoth;
const trimEnd = (value, trim) => {
return value.endsWith(trim) ? value.substring(0, value.length - trim.length) : value;
};
exports.trimEnd = trimEnd;
const trimStart = (value, trim) => {
return value.startsWith(trim) ? value.substring(trim.length) : value;
};
exports.trimStart = trimStart;
const adjustUrl = (urlOrPath, opts) => {
let url = typeof urlOrPath === 'object' ? urlOrPath.toString() : urlOrPath;
if (opts === null || opts === void 0 ? void 0 : opts.append) {
url = (0, exports.trimEnd)(url, '/') + '/' + (0, exports.trimStart)(opts.append, '/');
}
if (opts === null || opts === void 0 ? void 0 : opts.prepend) {
if (opts.prepend.includes('://')) {
// includes domain/hostname
if (!url.startsWith(opts.prepend)) {
url = (0, exports.trimEnd)(opts.prepend, '/') + '/' + (0, exports.trimStart)(url, '/');
}
}
else {
// path only for prepend
let host = '';
let path = url;
if (url.includes('://')) {
// includes domain/hostname
host = new URL(url).host;
path = new URL(url).pathname;
}
if (!path.startsWith(opts.prepend)) {
if (host && host !== '') {
url = (0, exports.trimEnd)(host, '/');
}
url += (0, exports.trimEnd)(url, '/') + '/' + (0, exports.trimBoth)(opts.prepend, '/') + '/' + (0, exports.trimStart)(path, '/');
}
}
}
if (opts === null || opts === void 0 ? void 0 : opts.stripSlashStart) {
url = (0, exports.trimStart)(url, '/');
}
if (opts === null || opts === void 0 ? void 0 : opts.stripSlashEnd) {
url = (0, exports.trimEnd)(url, '/');
}
if (typeof urlOrPath === 'string') {
return url;
}
return new URL(url);
};
exports.adjustUrl = adjustUrl;
//# sourceMappingURL=HttpUtils.js.map