@nauth-toolkit/client-angular 0.1.100 → 0.1.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -198,6 +198,7 @@ export function createNAuthAuthHttpInterceptor(params) {
|
|
|
198
198
|
const statusCode = getStatusCode(err);
|
|
199
199
|
// Refresh failed with 401 => session expired.
|
|
200
200
|
// Clear *local* SDK state so guards/pages don't think the user is still logged in after navigation/reload.
|
|
201
|
+
// IMPORTANT: This also clears challenge sessions and OAuth state to prevent ghost states.
|
|
201
202
|
if (statusCode === 401) {
|
|
202
203
|
// Best-effort: also clear CSRF cookie in cookies mode (non-httpOnly).
|
|
203
204
|
if (tokenDelivery === 'cookies') {
|
|
@@ -246,4 +247,4 @@ export function createNAuthAuthHttpInterceptor(params) {
|
|
|
246
247
|
}));
|
|
247
248
|
}))));
|
|
248
249
|
}
|
|
249
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1pbnRlcmNlcHRvci5zaGFyZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2F1dGgtaW50ZXJjZXB0b3Iuc2hhcmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBYyxpQkFBaUIsRUFBeUMsTUFBTSxzQkFBc0IsQ0FBQztBQUU1RyxPQUFPLEVBQ0wsZUFBZSxFQUVmLFVBQVUsRUFDVixRQUFRLEVBQ1IsSUFBSSxFQUNKLEdBQUcsRUFDSCxFQUFFLEVBQ0YsV0FBVyxFQUNYLFNBQVMsRUFDVCxVQUFVLEdBQ1gsTUFBTSxNQUFNLENBQUM7QUFJZDs7Ozs7Ozs7R0FRRztBQUVILCtFQUErRTtBQUMvRSwwQ0FBMEM7QUFDMUMsK0VBQStFO0FBQy9FLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztBQUN6QixNQUFNLG1CQUFtQixHQUFHLElBQUksZUFBZSxDQUFnQixJQUFJLENBQUMsQ0FBQztBQUNyRSxJQUFJLGdCQUFnQixHQUE4QixJQUFJLENBQUM7QUFDdkQsTUFBTSxlQUFlLEdBQUcsSUFBSSxPQUFPLEVBQXdCLENBQUM7QUFFNUQsK0VBQStFO0FBQy9FLHlCQUF5QjtBQUN6QiwrRUFBK0U7QUFFL0U7Ozs7R0FJRztBQUNILFNBQVMsYUFBYSxDQUFDLEtBQWM7SUFDbkMsSUFBSSxLQUFLLFlBQVksaUJBQWlCO1FBQUUsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDO0lBQzVELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksWUFBWSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3pFLE1BQU0sVUFBVSxHQUFJLEtBQWtDLENBQUMsVUFBVSxDQUFDO1FBQ2xFLE9BQU8sT0FBTyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUM1RCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxD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QUFDLElBQUksQ0FBQyxDQUFDO1lBQy9FLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRUQsT0FBTyxlQUFlLENBQUMsSUFBSSxDQUN6QixTQUFTLENBQUMsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUM1QixJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsSUFBSSxDQUN4QixVQUFVLENBQUMsQ0FBQyxLQUFjLEVBQUUsRUFBRTtRQUM1QixNQUFNLFlBQVksR0FDaEIsS0FBSyxZQUFZLGlCQUFpQixJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssR0FBRyxJQUFJLGVBQWUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFN0csSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ2xCLE9BQU8sVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLENBQUM7UUFFRCxlQUFlLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXpCLE9BQU8sa0JBQWtCLEVBQUUsQ0FBQyxJQUFJLENBQzlCLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ2xCLE1BQU0sUUFBUSxHQUFHLGlCQUFpQixDQUFDLGVBQWUsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN2RixlQUFlLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzlCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDLENBQUMsQ0FDSCxDQUNGLENBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50LCBIdHRwRXJyb3JSZXNwb25zZSwgSHR0cEV2ZW50LCBIdHRwSGFuZGxlckZuLCBIdHRwUmVxdWVzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIE9ic2VydmFibGUsXG4gIGNhdGNoRXJyb3IsXG4gIGZpbmFsaXplLFxuICBmcm9tLFxuICBtYXAsXG4gIG9mLFxuICBzaGFyZVJlcGxheSxcbiAgc3dpdGNoTWFwLFxuICB0aHJvd0Vycm9yLFxufSBmcm9tICdyeGpzJztcbmltcG9ydCB0eXBlIHsgTkF1dGhDbGllbnRDb25maWcgfSBmcm9tICdAbmF1dGgtdG9vbGtpdC9jbGllbnQnO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLi9uZ21vZHVsZS9hdXRoLnNlcnZpY2UnO1xuXG4vKipcbiAqIFNoYXJlZCBpbnRlcmNlcHRvciBsb2dpYyBmb3IgYm90aDpcbiAqIC0gRnVuY3Rpb25hbCBpbnRlcmNlcHRvciAoQW5ndWxhciAxNysgc3RhbmRhbG9uZSlcbiAqIC0gQ2xhc3MtYmFzZWQgaW50ZXJjZXB0b3IgKE5nTW9kdWxlIGFwcHMpXG4gKlxuICogV0hZOlxuICogLSBLZWVwIG9uZSBpbXBsZW1lbnRhdGlvbiBmb3IgY29va2llcyArIGpzb24gbW9kZSBiZWhhdmlvci5cbiAqIC0gQXZvaWQgZGl2ZXJnZW5jZSBiZXR3ZWVuIHN0YW5kYWxvbmUgYW5kIE5nTW9kdWxlIGludGVncmF0aW9ucy5cbiAqL1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBSZWZyZXNoIHN0YXRlIG1hbmFnZW1lbnQgKG1vZHVsZS1sZXZlbClcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmxldCBpc1JlZnJlc2hpbmcgPSBmYWxzZTtcbmNvbnN0IHJlZnJlc2hUb2tlblN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZyB8IG51bGw+KG51bGwpO1xubGV0IHJlZnJlc2hJbkZsaWdodCQ6IE9ic2VydmFibGU8c3RyaW5nPiB8IG51bGwgPSBudWxsO1xuY29uc3QgcmV0cmllZFJlcXVlc3RzID0gbmV3IFdlYWtTZXQ8SHR0cFJlcXVlc3Q8dW5rbm93bj4+KCk7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEVycm9yICsgY29va2llIGhlbHBlcnNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBTYWZlbHkgZXh0cmFjdCBIVFRQIHN0YXR1cyBjb2RlIGZyb20gZWl0aGVyOlxuICogLSBBbmd1bGFyIEh0dHBFcnJvclJlc3BvbnNlIChIdHRwQ2xpZW50IGNhbGxzKVxuICogLSBTREsgTkF1dGhDbGllbnRFcnJvciAodGhyb3duIGJ5IHRoZSBTREsncyBIdHRwQWRhcHRlcilcbiAqL1xuZnVuY3Rpb24gZ2V0U3RhdHVzQ29kZShlcnJvcjogdW5rbm93bik6IG51bWJlciB8IG51bGwge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSkgcmV0dXJuIGVycm9yLnN0YXR1cztcbiAgaWYgKHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCcgJiYgZXJyb3IgIT09IG51bGwgJiYgJ3N0YXR1c0NvZGUnIGluIGVycm9yKSB7XG4gICAgY29uc3Qgc3RhdHVzQ29kZSA9IChlcnJvciBhcyB7IHN0YXR1c0NvZGU/OiB1bmtub3duIH0pLnN0YXR1c0NvZGU7XG4gICAgcmV0dXJuIHR5cGVvZiBzdGF0dXNDb2RlID09PSAnbnVtYmVyJyA/IHN0YXR1c0NvZGUgOiBudWxsO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIEJlc3QtZWZmb3J0IENTUkYgY29va2llIGNsZWFyaW5nIChub24taHR0cE9ubHkpLlxuICpcbiAqIFdBUk5JTkc6IFRoaXMgY2Fubm90IGNsZWFyIGh0dHBPbmx5IGF1dGggY29va2llcyAoYWNjZXNzL3JlZnJlc2gvZGV2aWNlKS5cbiAqIFRob3NlIG11c3QgYmUgY2xlYXJlZCBieSB0aGUgYmFja2VuZCBvbiByZWZyZXNoL2xvZ291dC5cbiAqL1xuZnVuY3Rpb24gY2xlYXJDc3JmQ29va2llKGJhc2VVcmw6IHN0cmluZywgY29va2llTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG5cbiAgLy8gV0hZOiBDb29raWUgZG9tYWluIGhhbmRsaW5nIGRpZmZlcnMgYmV0d2VlbiBsb2NhbGhvc3QgYW5kIHJlYWwgZG9tYWlucy5cbiAgLy8gV2UgdHJ5IHRvIGNsZWFyIHdpdGggYW4gZXhwbGljaXQgZG9tYWluIChpZiBhdmFpbGFibGUpLCB0aGVuIHdpdGhvdXQuXG4gIHRyeSB7XG4gICAgY29uc3QgdXJsID0gbmV3IFVSTChiYXNlVXJsKTtcbiAgICBkb2N1bWVudC5jb29raWUgPSBgJHtjb29raWVOYW1lfT07IGV4cGlyZXM9VGh1LCAwMSBKYW4gMTk3MCAwMDowMDowMCBVVEM7IHBhdGg9LzsgZG9tYWluPSR7dXJsLmhvc3RuYW1lfWA7XG4gICAgZG9jdW1lbnQuY29va2llID0gYCR7Y29va2llTmFtZX09OyBleHBpcmVzPVRodSwgMDEgSmFuIDE5NzAgMDA6MDA6MDAgVVRDOyBwYXRoPS9gO1xuICB9IGNhdGNoIHtcbiAgICBkb2N1bWVudC5jb29raWUgPSBgJHtjb29raWVOYW1lfT07IGV4cGlyZXM9VGh1LCAwMSBKYW4gMTk3MCAwMDowMDowMCBVVEM7IHBhdGg9L2A7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgQ1NSRiB0b2tlbiBmcm9tIGNvb2tpZS5cbiAqXG4gKiBAcGFyYW0gY29va2llTmFtZSAtIE5hbWUgb2YgdGhlIENTUkYgY29va2llIChmcm9tIGNvbmZpZy5jc3JmLmNvb2tpZU5hbWUpXG4gKiBAcmV0dXJucyBDU1JGIHRva2VuIHZhbHVlIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gKi9cbmZ1bmN0aW9uIGdldENzcmZUb2tlbihjb29raWVOYW1lOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBudWxsO1xuICAvLyBFc2NhcGUgc3BlY2lhbCByZWdleCBjaGFyYWN0ZXJzIGluIGNvb2tpZSBuYW1lIHRvIHByZXZlbnQgaW5qZWN0aW9uXG4gIGNvbnN0IGVzY2FwZWRDb29raWVOYW1lID0gY29va2llTmFtZS5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpO1xuICBjb25zdCBtYXRjaCA9IGRvY3VtZW50LmNvb2tpZS5tYXRjaChuZXcgUmVnRXhwKGAoXnwgKSR7ZXNjYXBlZENvb2tpZU5hbWV9PShbXjtdKylgKSk7XG4gIHJldHVybiBtYXRjaCA/IGRlY29kZVVSSUNvbXBvbmVudChtYXRjaFsyXSkgOiBudWxsO1xufVxuXG4vKipcbiAqIEJ1aWxkIHJldHJ5IHJlcXVlc3Qgd2l0aCBhcHByb3ByaWF0ZSBhdXRoLlxuICpcbiAqIEluIGNvb2tpZXMgbW9kZTogQnJvd3NlciBhdXRvbWF0aWNhbGx5IHNlbmRzIHVwZGF0ZWQgaHR0cE9ubHkgY29va2llcyAoYWNjZXNzL3JlZnJlc2ggdG9rZW5zKS5cbiAqIFdlIG11c3QgcmUtcmVhZCBDU1JGIHRva2VuIGFmdGVyIHJlZnJlc2ggdG8gYXZvaWQgc3RhbGUgaGVhZGVycy5cbiAqXG4gKiBJbiBKU09OIG1vZGU6IENsb25lcyB0aGUgcmVxdWVzdCBhbmQgYWRkcyB0aGUgbmV3IEJlYXJlciB0b2tlbi5cbiAqL1xuZnVuY3Rpb24gYnVpbGRSZXRyeVJlcXVlc3QoXG4gIG9yaWdpbmFsUmVxOiBIdHRwUmVxdWVzdDx1bmtub3duPixcbiAgdG9rZW5EZWxpdmVyeTogc3RyaW5nLFxuICBuZXdUb2tlbj86IHN0cmluZyB8IG51bGwsXG4gIGNzcmZDb25maWc/OiB7IGNvb2tpZU5hbWU/OiBzdHJpbmc7IGhlYWRlck5hbWU/OiBzdHJpbmcgfSxcbik6IEh0dHBSZXF1ZXN0PHVua25vd24+IHtcbiAgaWYgKHRva2VuRGVsaXZlcnkgPT09ICdqc29uJyAmJiBuZXdUb2tlbiAmJiBuZXdUb2tlbiAhPT0gJ3N1Y2Nlc3MnKSB7XG4gICAgcmV0dXJuIG9yaWdpbmFsUmVxLmNsb25lKHsgc2V0SGVhZGVyczogeyBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7bmV3VG9rZW59YCB9IH0pO1xuICB9XG5cbiAgaWYgKHRva2VuRGVsaXZlcnkgPT09ICdjb29raWVzJyAmJiBbJ1BPU1QnLCAnUFVUJywgJ1BBVENIJywgJ0RFTEVURSddLmluY2x1ZGVzKG9yaWdpbmFsUmVxLm1ldGhvZCkpIHtcbiAgICBjb25zdCBjc3JmQ29va2llTmFtZSA9IGNzcmZDb25maWc/LmNvb2tpZU5hbWUgPz8gJ25hdXRoX2NzcmZfdG9rZW4nO1xuICAgIGNvbnN0IGNzcmZIZWFkZXJOYW1lID0gY3NyZkNvbmZpZz8uaGVhZGVyTmFtZSA/PyAneC1jc3JmLXRva2VuJztcbiAgICAvLyBBbHdheXMgcmVmcmVzaCBDU1JGIHRva2VuIG9uIHJldHJ5IChldmVuIGlmIGl0IGV4aXN0cywgZ2V0IGZyZXNoIG9uZSlcbiAgICBjb25zdCBmcmVzaENzcmZUb2tlbiA9IGdldENzcmZUb2tlbihjc3JmQ29va2llTmFtZSk7XG4gICAgaWYgKGZyZXNoQ3NyZlRva2VuKSB7XG4gICAgICByZXR1cm4gb3JpZ2luYWxSZXEuY2xvbmUoeyBzZXRIZWFkZXJzOiB7IFtjc3JmSGVhZGVyTmFtZV06IGZyZXNoQ3NyZlRva2VuIH0gfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9yaWdpbmFsUmVxO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTkF1dGhBdXRoSHR0cEludGVyY2VwdG9yKHBhcmFtczoge1xuICBjb25maWc6IE5BdXRoQ2xpZW50Q29uZmlnO1xuICBodHRwOiBIdHRwQ2xpZW50O1xuICBhdXRoU2VydmljZTogQXV0aFNlcnZpY2U7XG4gIHJvdXRlcjogUm91dGVyO1xuICBuZXh0OiBIdHRwSGFuZGxlckZuO1xuICByZXE6IEh0dHBSZXF1ZXN0PHVua25vd24+O1xufSk6IE9ic2VydmFibGU8SHR0cEV2ZW50PHVua25vd24+PiB7XG4gIGNvbnN0IHsgY29uZmlnLCBhdXRoU2VydmljZSwgcm91dGVyLCBuZXh0LCByZXEgfSA9IHBhcmFtcztcblxuICBjb25zdCB0b2tlbkRlbGl2ZXJ5ID0gY29uZmlnLnRva2VuRGVsaXZlcnk7XG4gIGNvbnN0IGJhc2VVcmwgPSBjb25maWcuYmFzZVVybDtcbiAgY29uc3QgZW5kcG9pbnRzID0gY29uZmlnLmVuZHBvaW50cyA/PyB7fTtcbiAgY29uc3QgYXV0aFBhdGhQcmVmaXggPSBjb25maWcuYXV0aFBhdGhQcmVmaXg7XG5cbiAgLy8gQnVpbGQgcmVmcmVzaCBwYXRoIHdpdGggYXV0aFBhdGhQcmVmaXggaWYgY29uZmlndXJlZCAobWF0Y2hlcyBjb3JlIGNsaWVudCBidWlsZFVybCBsb2dpYyBleGFjdGx5KVxuICAvLyBVc2UgZGVmYXVsdCAnL3JlZnJlc2gnIGlmIGVuZHBvaW50cy5yZWZyZXNoIGlzIG5vdCBkZWZpbmVkXG4gIGNvbnN0IHJlZnJlc2hQYXRoID0gZW5kcG9pbnRzPy5yZWZyZXNoID8/ICcvcmVmcmVzaCc7XG4gIGNvbnN0IG5vcm1hbGl6ZWRSZWZyZXNoUGF0aCA9IHJlZnJlc2hQYXRoLnN0YXJ0c1dpdGgoJy8nKSA/IHJlZnJlc2hQYXRoIDogYC8ke3JlZnJlc2hQYXRofWA7XG5cbiAgLy8gQ2hlY2sgaWYgYmFzZVVybCBhbHJlYWR5IGVuZHMgd2l0aCBhdXRoUGF0aFByZWZpeCB0byBhdm9pZCBkb3VibGUtcHJlZml4aW5nXG4gIC8vIFRoaXMgbXVzdCBtYXRjaCB0aGUgY29yZSBjbGllbnQncyBidWlsZFVybCBsb2dpYyBleGFjdGx5XG4gIGNvbnN0IGJhc2VVcmxFbmRzV2l0aFByZWZpeCA9IGF1dGhQYXRoUHJlZml4ICYmIGJhc2VVcmwuZW5kc1dpdGgoYXV0aFBhdGhQcmVmaXgpO1xuXG4gIGNvbnN0IHNob3VsZEFkZFByZWZpeCA9IGF1dGhQYXRoUHJlZml4ICYmICFiYXNlVXJsRW5kc1dpdGhQcmVmaXggJiYgIW5vcm1hbGl6ZWRSZWZyZXNoUGF0aC5zdGFydHNXaXRoKGF1dGhQYXRoUHJlZml4KTtcbiAgY29uc3QgZWZmZWN0aXZlUmVmcmVzaFBhdGggPSBzaG91bGRBZGRQcmVmaXggPyBgJHthdXRoUGF0aFByZWZpeH0ke25vcm1hbGl6ZWRSZWZyZXNoUGF0aH1gIDogbm9ybWFsaXplZFJlZnJlc2hQYXRoO1xuXG4gIGNvbnN0IGxvZ2luUGF0aCA9IGVuZHBvaW50cy5sb2dpbiA/PyAnL2xvZ2luJztcbiAgY29uc3Qgc2lnbnVwUGF0aCA9IGVuZHBvaW50cy5zaWdudXAgPz8gJy9zaWdudXAnO1xuICBjb25zdCBzb2NpYWxFeGNoYW5nZVBhdGggPSBlbmRwb2ludHMuc29jaWFsRXhjaGFuZ2UgPz8gJy9zb2NpYWwvZXhjaGFuZ2UnO1xuXG4gIGNvbnN0IGlzQXV0aEFwaVJlcXVlc3QgPSByZXEudXJsLmluY2x1ZGVzKGJhc2VVcmwpO1xuICAvLyBDaGVjayBpZiByZXF1ZXN0IGlzIHRvIHJlZnJlc2ggZW5kcG9pbnQgKHVzaW5nIGVmZmVjdGl2ZSBwYXRoIHdpdGggYXV0aFBhdGhQcmVmaXgpXG4gIGNvbnN0IGlzUmVmcmVzaEVuZHBvaW50ID0gcmVxLnVybC5pbmNsdWRlcyhlZmZlY3RpdmVSZWZyZXNoUGF0aCk7XG4gIGNvbnN0IGlzUHVibGljRW5kcG9pbnQgPVxuICAgIHJlcS51cmwuaW5jbHVkZXMobG9naW5QYXRoKSB8fCByZXEudXJsLmluY2x1ZGVzKHNpZ251cFBhdGgpIHx8IHJlcS51cmwuaW5jbHVkZXMoc29jaWFsRXhjaGFuZ2VQYXRoKTtcbiAgY29uc3Qgc2hvdWxkSW50ZXJjZXB0ID0gaXNBdXRoQXBpUmVxdWVzdCAmJiAhaXNSZWZyZXNoRW5kcG9pbnQgJiYgIWlzUHVibGljRW5kcG9pbnQ7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBCdWlsZCByZXF1ZXN0IGZvciBjb29raWVzIG1vZGUgKHdpdGhDcmVkZW50aWFscyArIENTUkYpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gSU1QT1JUQU5UOiBXaGVuIHVzaW5nIEFuZ3VsYXJIdHRwQWRhcHRlciwgaGVhZGVycyBmcm9tIGJ1aWxkSGVhZGVycygpIGFyZSBwYXNzZWRcbiAgLy8gdG8gSHR0cENsaWVudC5yZXF1ZXN0KCkgYXMgYSBwbGFpbiBvYmplY3QuIEFuZ3VsYXIgY29udmVydHMgdGhlc2UgdG8gSHR0cEhlYWRlcnNcbiAgLy8gYW5kIGNyZWF0ZXMgYW4gSHR0cFJlcXVlc3QuIEhvd2V2ZXIsIHdlIGNhbm5vdCByZWx5IG9uIGJ1aWxkSGVhZGVycygpIHRvIGFkZCBDU1JGXG4gIC8vIGluIEFuZ3VsYXIgY29udGV4dCBiZWNhdXNlOlxuICAvLyAxLiBoYXNXaW5kb3coKSBtaWdodCByZXR1cm4gZmFsc2UgaW4gU1NSIGNvbnRleHRzXG4gIC8vIDIuIEhlYWRlcnMgbWlnaHQgbm90IGJlIHByb3Blcmx5IG1lcmdlZCBpbnRvIHRoZSBIdHRwUmVxdWVzdCB0aGF0IGludGVyY2VwdG9ycyByZWNlaXZlXG4gIC8vIDMuIFRoZSBpbnRlcmNlcHRvciBpcyB0aGUgYXV0aG9yaXRhdGl2ZSBwbGFjZSBmb3IgQ1NSRiBpbiBBbmd1bGFyIGFwcHNcbiAgLy9cbiAgLy8gVGhlcmVmb3JlLCB0aGUgaW50ZXJjZXB0b3IgQUxXQVlTIGFkZHMgQ1NSRiBmb3IgbXV0YXRpbmcgbWV0aG9kcyBpbiBjb29raWVzIG1vZGUsXG4gIC8vIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciBidWlsZEhlYWRlcnMoKSBhZGRlZCBpdCAoZm9yIHZhbmlsbGEgY2xpZW50cykuXG4gIGxldCBhdXRoUmVxID0gcmVxO1xuICBpZiAodG9rZW5EZWxpdmVyeSA9PT0gJ2Nvb2tpZXMnKSB7XG4gICAgYXV0aFJlcSA9IGF1dGhSZXEuY2xvbmUoeyB3aXRoQ3JlZGVudGlhbHM6IHRydWUgfSk7XG4gICAgLy8gQWRkIENTUkYgdG9rZW4gZm9yIG11dGF0aW5nIG1ldGhvZHMgKFBPU1QsIFBVVCwgUEFUQ0gsIERFTEVURSlcbiAgICAvLyBBbHdheXMgYWRkIGl0IGhlcmUgLSBkb24ndCByZWx5IG9uIGJ1aWxkSGVhZGVycygpIGluIEFuZ3VsYXIgY29udGV4dFxuICAgIC8vIEFkZCBDU1JGIHRva2VuIGZvciBtdXRhdGluZyBtZXRob2RzIChQT1NULCBQVVQsIFBBVENILCBERUxFVEUpXG4gICAgLy8gVGhpcyBydW5zIGZvciBBTEwgcmVxdWVzdHMgaW4gY29va2llcyBtb2RlLCBub3QganVzdCBhdXRoIEFQSSByZXF1ZXN0c1xuICAgIC8vIFRoaXMgZW5zdXJlcyBDU1JGIHByb3RlY3Rpb24gZm9yIGFsbCBtdXRhdGluZyBvcGVyYXRpb25zXG4gICAgaWYgKFsnUE9TVCcsICdQVVQnLCAnUEFUQ0gnLCAnREVMRVRFJ10uaW5jbHVkZXMocmVxLm1ldGhvZCkpIHtcbiAgICAgIC8vIFJlc3BlY3QgdXNlcidzIENTUkYgY29uZmlnLCBmYWxsYmFjayB0byBkZWZhdWx0cyBpZiBub3QgcHJvdmlkZWRcbiAgICAgIC8vIFRoZXNlIGRlZmF1bHRzIG11c3QgbWF0Y2ggdGhlIGJhY2tlbmQncyBDU1JGIGNvbmZpZ3VyYXRpb25cbiAgICAgIGNvbnN0IGNzcmZDb29raWVOYW1lID0gY29uZmlnLmNzcmY/LmNvb2tpZU5hbWUgPz8gJ25hdXRoX2NzcmZfdG9rZW4nO1xuICAgICAgY29uc3QgY3NyZkhlYWRlck5hbWUgPSBjb25maWcuY3NyZj8uaGVhZGVyTmFtZSA/PyAneC1jc3JmLXRva2VuJztcblxuICAgICAgLy8gR2V0IENTUkYgdG9rZW4gZnJvbSBjb29raWUgdXNpbmcgdGhlIGNvbmZpZ3VyZWQgY29va2llIG5hbWVcbiAgICAgIGNvbnN0IGNzcmZUb2tlbiA9IGdldENzcmZUb2tlbihjc3JmQ29va2llTmFtZSk7XG5cbiAgICAgIGlmIChjc3JmVG9rZW4pIHtcbiAgICAgICAgLy8gVXNlIHNldEhlYWRlcnMgd2hpY2ggd2lsbCBvdmVycmlkZSBpZiBhbHJlYWR5IGV4aXN0cyAoZnJvbSBidWlsZEhlYWRlcnMpXG4gICAgICAgIC8vIFRoaXMgZW5zdXJlcyBDU1JGIGlzIGFsd2F5cyBwcmVzZW50IGZvciBERUxFVEUgYW5kIG90aGVyIG11dGF0aW5nIG1ldGhvZHNcbiAgICAgICAgYXV0aFJlcSA9IGF1dGhSZXEuY2xvbmUoeyBzZXRIZWFkZXJzOiB7IFtjc3JmSGVhZGVyTmFtZV06IGNzcmZUb2tlbiB9IH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ1NSRiB0b2tlbiBub3QgZm91bmQgLSB0aGlzIGNvdWxkIGhhcHBlbiBpZjpcbiAgICAgICAgLy8gMS4gQ29va2llIGRvZXNuJ3QgZXhpc3QgKGJlZm9yZSBmaXJzdCBsb2dpbiwgYWZ0ZXIgbG9nb3V0LCBvciBjb29raWUgZXhwaXJlZClcbiAgICAgICAgLy8gMi4gQ29va2llIG5hbWUgbWlzbWF0Y2ggKGNoZWNrIGNvbmZpZy5jc3JmLmNvb2tpZU5hbWUgbWF0Y2hlcyBiYWNrZW5kKVxuICAgICAgICAvLyAzLiBDb29raWUgaXMgaHR0cE9ubHkgYW5kIGNhbid0IGJlIHJlYWQgKGJ1dCBDU1JGIGNvb2tpZXMgc2hvdWxkIGJlIHJlYWRhYmxlKVxuICAgICAgICAvLyBUaGUgYmFja2VuZCBzaG91bGQgaGFuZGxlIG1pc3NpbmcgQ1NSRiB0b2tlbnMgYXBwcm9wcmlhdGVseSAocmV0dXJuIDQwMyBvciBzaW1pbGFyKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gSlNPTiBtb2RlOiBhdHRhY2ggQXV0aG9yaXphdGlvbiBoZWFkZXIgZm9yIEh0dHBDbGllbnQgY2FsbHNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBTaW1wbGUgYXBwcm9hY2g6IGF0dGFjaCB0b2tlbiBpZiBhdmFpbGFibGUsIGxldCBiYWNrZW5kIHZhbGlkYXRlXG4gIC8vIEhhbmRsZSA0MDEgcmVhY3RpdmVseSAobWF0Y2hlcyBvbGQgd29ya2luZyBpbXBsZW1lbnRhdGlvbilcbiAgY29uc3QgYXR0YWNoSnNvbkF1dGgkID1cbiAgICB0b2tlbkRlbGl2ZXJ5ID09PSAnanNvbicgJiYgc2hvdWxkSW50ZXJjZXB0ICYmICFhdXRoUmVxLmhlYWRlcnMuaGFzKCdBdXRob3JpemF0aW9uJylcbiAgICAgID8gZnJvbShhdXRoU2VydmljZS5nZXRBY2Nlc3NUb2tlbigpKS5waXBlKFxuICAgICAgICAgIHN3aXRjaE1hcCgodG9rZW4pID0+IHtcbiAgICAgICAgICAgIGlmICh0b2tlbikge1xuICAgICAgICAgICAgICByZXR1cm4gb2YoYXV0aFJlcS5jbG9uZSh7IHNldEhlYWRlcnM6IHsgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke3Rva2VufWAgfSB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2YoYXV0aFJlcSk7XG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgIDogb2YoYXV0aFJlcSk7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBSZWZyZXNoIGNvb3JkaW5hdGlvblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGNvbnN0IGdldE9yU3RhcnRSZWZyZXNoJCA9ICgpOiBPYnNlcnZhYmxlPHN0cmluZz4gPT4ge1xuICAgIGlmIChyZWZyZXNoSW5GbGlnaHQkKSByZXR1cm4gcmVmcmVzaEluRmxpZ2h0JDtcblxuICAgIC8vIFdIWTogV2Ugd2FudCB0byBlbnN1cmUgb25seSBvbmUgcmVmcmVzaCByZXF1ZXN0IGlzIGluIGZsaWdodCBhdCBhbnkgdGltZS5cbiAgICAvLyBBbGwgcmVxdWVzdHMgKGluY2x1ZGluZyB0aG9zZSB0aGF0IGhhdmVuJ3QgaGl0IHRoZSBiYWNrZW5kIHlldCkgc2hvdWxkIHdhaXQgZm9yXG4gICAgLy8gdGhlIHNhbWUgcmVmcmVzaCByZXN1bHQgdG8gYXZvaWQgYSBidXJzdCBvZiA0MDFzIGFuZCBwb3RlbnRpYWwgV0FGL3JhdGUtbGltaXQgaXNzdWVzLlxuICAgIGlzUmVmcmVzaGluZyA9IHRydWU7XG4gICAgcmVmcmVzaFRva2VuU3ViamVjdC5uZXh0KG51bGwpO1xuXG4gICAgLy8gV0hZOiBBbHdheXMgcmVmcmVzaCB2aWEgdGhlIGNvcmUgY2xpZW50LlxuICAgIC8vIC0gRW5zdXJlcyBhdXRoUGF0aFByZWZpeCArIGRlZmF1bHQgZW5kcG9pbnRzIGFyZSBhcHBsaWVkIGNvbnNpc3RlbnRseSAoZml4ZXMgL3JlZnJlc2ggdnMgL2F1dGgvcmVmcmVzaCkuXG4gICAgLy8gLSBDZW50cmFsaXplcyBDU1JGICsgY3JlZGVudGlhbHMgaGFuZGxpbmcgaW4gb25lIHBsYWNlLlxuICAgIGNvbnN0IHJlZnJlc2hSZXF1ZXN0JCA9IGZyb20oYXV0aFNlcnZpY2UuZ2V0Q2xpZW50KCkucmVmcmVzaFRva2VucygpKTtcblxuICAgIHJlZnJlc2hJbkZsaWdodCQgPSByZWZyZXNoUmVxdWVzdCQucGlwZShcbiAgICAgIG1hcCgocmVzcG9uc2UpID0+IHtcbiAgICAgICAgLy8gQ29va2llcyBtb2RlOiBzdWNjZXNzIGlzIGVub3VnaCAodG9rZW5zIGFyZSBpbiBodHRwT25seSBjb29raWVzKS5cbiAgICAgICAgLy8gSlNPTiBtb2RlOiB3ZSBuZWVkIHRoZSBuZXcgYWNjZXNzIHRva2VuIHRvIHJldHJ5ICsgdW5ibG9jayBxdWV1ZWQgcmVxdWVzdHMuXG4gICAgICAgIGNvbnN0IG5ld1Rva2VuID0gdG9rZW5EZWxpdmVyeSA9PT0gJ2pzb24nID8gcmVzcG9uc2UuYWNjZXNzVG9rZW4gOiAnc3VjY2Vzcyc7XG5cbiAgICAgICAgaWYgKHRva2VuRGVsaXZlcnkgPT09ICdqc29uJyAmJiAoIW5ld1Rva2VuIHx8IG5ld1Rva2VuID09PSAnc3VjY2VzcycpKSB7XG4gICAgICAgICAgLy8g4pqg77iPIFdBUk5JTkc6IFdpdGhvdXQgYW4gYWNjZXNzIHRva2VuIHdlIGNhbm5vdCBzYWZlbHkgcmV0cnkgcmVxdWVzdHMgaW4gSlNPTiBtb2RlLlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVG9rZW4gcmVmcmVzaCBkaWQgbm90IHJldHVybiBhbiBhY2Nlc3MgdG9rZW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlZnJlc2hUb2tlblN1YmplY3QubmV4dChuZXdUb2tlbiA/PyAnc3VjY2VzcycpO1xuICAgICAgICByZXR1cm4gbmV3VG9rZW4gPz8gJ3N1Y2Nlc3MnO1xuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKChlcnIpID0+IHtcbiAgICAgICAgcmVmcmVzaFRva2VuU3ViamVjdC5uZXh0KG51bGwpO1xuXG4gICAgICAgIGNvbnN0IHN0YXR1c0NvZGUgPSBnZXRTdGF0dXNDb2RlKGVycik7XG5cbiAgICAgICAgLy8gUmVmcmVzaCBmYWlsZWQgd2l0aCA0MDEgPT4gc2Vzc2lvbiBleHBpcmVkLlxuICAgICAgICAvLyBDbGVhciAqbG9jYWwqIFNESyBzdGF0ZSBzbyBndWFyZHMvcGFnZXMgZG9uJ3QgdGhpbmsgdGhlIHVzZXIgaXMgc3RpbGwgbG9nZ2VkIGluIGFmdGVyIG5hdmlnYXRpb24vcmVsb2FkLlxuICAgICAgICBpZiAoc3RhdHVzQ29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgLy8gQmVzdC1lZmZvcnQ6IGFsc28gY2xlYXIgQ1NSRiBjb29raWUgaW4gY29va2llcyBtb2RlIChub24taHR0cE9ubHkpLlxuICAgICAgICAgIGlmICh0b2tlbkRlbGl2ZXJ5ID09PSAnY29va2llcycpIHtcbiAgICAgICAgICAgIGNvbnN0IGNzcmZDb29raWVOYW1lID0gY29uZmlnLmNzcmY/LmNvb2tpZU5hbWUgPz8gJ25hdXRoX2NzcmZfdG9rZW4nO1xuICAgICAgICAgICAgY2xlYXJDc3JmQ29va2llKGNvbmZpZy5iYXNlVXJsLCBjc3JmQ29va2llTmFtZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGZyb20oYXV0aFNlcnZpY2UuZ2V0Q2xpZW50KCkuY2xlYXJMb2NhbEF1dGhTdGF0ZSgpKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgLy8gQ2FsbCBvblNlc3Npb25FeHBpcmVkIGNhbGxiYWNrIGlmIGNvbmZpZ3VyZWRcbiAgICAgICAgICAgICAgY29uZmlnLm9uU2Vzc2lvbkV4cGlyZWQ/LigpO1xuXG4gICAgICAgICAgICAgIGlmIChjb25maWcucmVkaXJlY3RzPy5zZXNzaW9uRXhwaXJlZCkge1xuICAgICAgICAgICAgICAgIHJvdXRlci5uYXZpZ2F0ZUJ5VXJsKGNvbmZpZy5yZWRpcmVjdHMuc2Vzc2lvbkV4cGlyZWQpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSBuYXZpZ2F0aW9uIGVycm9yc1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycik7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyKTtcbiAgICAgIH0pLFxuICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICBpc1JlZnJlc2hpbmcgPSBmYWxzZTtcbiAgICAgICAgcmVmcmVzaEluRmxpZ2h0JCA9IG51bGw7XG4gICAgICB9KSxcbiAgICAgIHNoYXJlUmVwbGF5KHsgYnVmZmVyU2l6ZTogMSwgcmVmQ291bnQ6IGZhbHNlIH0pLFxuICAgICk7XG5cbiAgICByZXR1cm4gcmVmcmVzaEluRmxpZ2h0JDtcbiAgfTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFByZS1yZXF1ZXN0IGdhdGluZzogYmxvY2sgcmVxdWVzdHMgd2hpbGUgcmVmcmVzaCBpcyBpbi1mbGlnaHRcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBXSFk6IFByZXZlbnQgbXVsdGlwbGUgcmVxdWVzdHMgZnJvbSBoaXR0aW5nIHRoZSBiYWNrZW5kIHdpdGggYW4gZXhwaXJlZCB0b2tlbiBhbmQgcmV0dXJuaW5nIDQwMS5cbiAgLy8gV2UgcXVldWUgYWxsIGF1dGggQVBJIGNhbGxzIGR1cmluZyByZWZyZXNoIGFuZCByZWxlYXNlIHRoZW0gb25jZSByZWZyZXNoIHN1Y2NlZWRzLlxuICBpZiAoc2hvdWxkSW50ZXJjZXB0ICYmIGlzUmVmcmVzaGluZyAmJiByZWZyZXNoSW5GbGlnaHQkKSB7XG4gICAgcmV0dXJuIHJlZnJlc2hJbkZsaWdodCQucGlwZShcbiAgICAgIHN3aXRjaE1hcCgodG9rZW4pID0+IHtcbiAgICAgICAgY29uc3QgZ2F0ZWRSZXEgPSBidWlsZFJldHJ5UmVxdWVzdChhdXRoUmVxLCB0b2tlbkRlbGl2ZXJ5LCB0b2tlbiwgY29uZmlnLmNzcmYpO1xuICAgICAgICByZXR1cm4gbmV4dChnYXRlZFJlcSk7XG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIGF0dGFjaEpzb25BdXRoJC5waXBlKFxuICAgIHN3aXRjaE1hcCgocmVxdWVzdFdpdGhBdXRoKSA9PlxuICAgICAgbmV4dChyZXF1ZXN0V2l0aEF1dGgpLnBpcGUoXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc2hvdWxkSGFuZGxlID1cbiAgICAgICAgICAgIGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UgJiYgZXJyb3Iuc3RhdHVzID09PSA0MDEgJiYgc2hvdWxkSW50ZXJjZXB0ICYmICFyZXRyaWVkUmVxdWVzdHMuaGFzKHJlcSk7XG5cbiAgICAgICAgICBpZiAoIXNob3VsZEhhbmRsZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHJpZWRSZXF1ZXN0cy5hZGQocmVxKTtcblxuICAgICAgICAgIHJldHVybiBnZXRPclN0YXJ0UmVmcmVzaCQoKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKCh0b2tlbikgPT4ge1xuICAgICAgICAgICAgICBjb25zdCByZXRyeVJlcSA9IGJ1aWxkUmV0cnlSZXF1ZXN0KHJlcXVlc3RXaXRoQXV0aCwgdG9rZW5EZWxpdmVyeSwgdG9rZW4sIGNvbmZpZy5jc3JmKTtcbiAgICAgICAgICAgICAgcmV0cmllZFJlcXVlc3RzLmFkZChyZXRyeVJlcSk7XG4gICAgICAgICAgICAgIHJldHVybiBuZXh0KHJldHJ5UmVxKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApLFxuICApO1xufVxuIl19
|
|
250
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1pbnRlcmNlcHRvci5zaGFyZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2F1dGgtaW50ZXJjZXB0b3Iuc2hhcmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBYyxpQkFBaUIsRUFBeUMsTUFBTSxzQkFBc0IsQ0FBQztBQUU1RyxPQUFPLEVBQ0wsZUFBZSxFQUVmLFVBQVUsRUFDVixRQUFRLEVBQ1IsSUFBSSxFQUNKLEdBQUcsRUFDSCxFQUFFLEVBQ0YsV0FBVyxFQUNYLFNBQVMsRUFDVCxVQUFVLEdBQ1gsTUFBTSxNQUFNLENBQUM7QUFJZDs7Ozs7Ozs7R0FRRztBQUVILCtFQUErRTtBQUMvRSwwQ0FBMEM7QUFDMUMsK0VBQStFO0FBQy9FLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztBQUN6QixNQUFNLG1CQUFtQixHQUFHLElBQUksZUFBZSxDQUFnQixJQUFJLENBQUMsQ0FBQztBQUNyRSxJQUFJLGdCQUFnQixHQUE4QixJQUFJLENBQUM7QUFDdkQsTUFBTSxlQUFlLEdBQUcsSUFBSSxPQUFPLEVBQXdCLENBQUM7QUFFNUQsK0VBQStFO0FBQy9FLHlCQUF5QjtBQUN6QiwrRUFBK0U7QUFFL0U7Ozs7R0FJRztBQUNILFNBQVMsYUFBYSxDQUFDLEtBQWM7SUFDbkMsSUFBSSxLQUFLLFlBQVksaUJBQWlCO1FBQUUsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDO0lBQzVELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksWUFBWSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3pFLE1BQU0sVUFBVSxHQUFJLEtBQWtDLENBQUMsVUFBVSxDQUFDO1FBQ2xFLE9BQU8sT0FBTyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUM1RCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLGVBQWUsQ0FBQyxPQUFlLEVBQUUsVUFBa0I7SUFDMUQsSUFBSSxPQUFPLFFBQVEsS0FBSyxXQUFXO1FBQUUsT0FBTztJQUU1QywwRUFBMEU7SUFDMUUsd0VBQXdFO0lBQ3hFLElBQUksQ0FBQztRQUNILE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzdCLFFBQVEsQ0FBQyxNQUFNLEdBQUcsR0FBRyxVQUFVLDREQUE0RCxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDMUcsUUFBUSxDQUFDLE1BQU0sR0FBRyxHQUFHLFVBQVUsa0RBQWtELENBQUM7SUFDcEYsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLFFBQVEsQ0FBQyxNQUFNLEdBQUcsR0FBRyxVQUFVLGtEQUFrRCxDQUFDO0lBQ3BGLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLFlBQVksQ0FBQyxVQUFrQjtJQUN0QyxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVc7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNqRCxzRUFBc0U7SUFDdEUsTUFBTSxpQkFBaUIsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzVFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLFFBQVEsaUJBQWlCLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDckYsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDckQsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFTLGlCQUFpQixDQUN4QixXQUFpQyxFQUNqQyxhQUFxQixFQUNyQixRQUF3QixFQUN4QixVQUF5RDtJQUV6RCxJQUFJLGFBQWEsS0FBSyxNQUFNLElBQUksUUFBUSxJQUFJLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUNuRSxPQUFPLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxhQUFhLEVBQUUsVUFBVSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNwRixDQUFDO0lBRUQsSUFBSSxhQUFhLEtBQUssU0FBUyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ25HLE1BQU0sY0FBYyxHQUFHLFVBQVUsRUFBRSxVQUFVLElBQUksa0JBQWtCLENBQUM7UUFDcEUsTUFBTSxjQUFjLEdBQUcsVUFBVSxFQUFFLFVBQVUsSUFBSSxjQUFjLENBQUM7UUFDaEUsd0VBQXdFO1FBQ3hFLE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNwRCxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLE9BQU8sV0FBVyxDQUFDLEtBQUssQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEVBQUUsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pGLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQztBQUVELE1BQU0sVUFBVSw4QkFBOEIsQ0FBQyxNQU85QztJQUNDLE1BQU0sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBRTFELE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7SUFDM0MsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUMvQixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQztJQUN6QyxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDO0lBRTdDLG9HQUFvRztJQUNwRyw2REFBNkQ7SUFDN0QsTUFBTSxXQUFXLEdBQUcsU0FBUyxFQUFFLE9BQU8sSUFBSSxVQUFVLENBQUM7SUFDckQsTUFBTSxxQkFBcUIsR0FBRyxXQUFXLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksV0FBVyxFQUFFLENBQUM7SUFFNUYsOEVBQThFO0lBQzlFLDJEQUEyRDtJQUMzRCxNQUFNLHFCQUFxQixHQUFHLGNBQWMsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBRWpGLE1BQU0sZUFBZSxHQUFHLGNBQWMsSUFBSSxDQUFDLHFCQUFxQixJQUFJLENBQUMscUJBQXFCLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3RILE1BQU0sb0JBQW9CLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQyxHQUFHLGNBQWMsR0FBRyxxQkFBcUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQztJQUVuSCxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxJQUFJLFFBQVEsQ0FBQztJQUM5QyxNQUFNLFVBQVUsR0FBRyxTQUFTLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQztJQUNqRCxNQUFNLGtCQUFrQixHQUFHLFNBQVMsQ0FBQyxjQUFjLElBQUksa0JBQWtCLENBQUM7SUFFMUUsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxxRkFBcUY7SUFDckYsTUFBTSxpQkFBaUIsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ2pFLE1BQU0sZ0JBQWdCLEdBQ3BCLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDdEcsTUFBTSxlQUFlLEdBQUcsZ0JBQWdCLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDO0lBRXBGLCtFQUErRTtJQUMvRSwwREFBMEQ7SUFDMUQsK0VBQStFO0lBQy9FLG1GQUFtRjtJQUNuRixtRkFBbUY7SUFDbkYsb0ZBQW9GO0lBQ3BGLDhCQUE4QjtJQUM5QixvREFBb0Q7SUFDcEQseUZBQXlGO0lBQ3pGLHlFQUF5RTtJQUN6RSxFQUFFO0lBQ0Ysb0ZBQW9GO0lBQ3BGLHVFQUF1RTtJQUN2RSxJQUFJLE9BQU8sR0FBRyxHQUFHLENBQUM7SUFDbEIsSUFBSSxhQUFhLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDaEMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNuRCxpRUFBaUU7UUFDakUsdUVBQXVFO1FBQ3ZFLGlFQUFpRTtRQUNqRSx5RUFBeUU7UUFDekUsMkRBQTJEO1FBQzNELElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDNUQsbUVBQW1FO1lBQ25FLDZEQUE2RDtZQUM3RCxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLFVBQVUsSUFBSSxrQkFBa0IsQ0FBQztZQUNyRSxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLFVBQVUsSUFBSSxjQUFjLENBQUM7WUFFakUsOERBQThEO1lBQzlELE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUUvQyxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLDJFQUEyRTtnQkFDM0UsNEVBQTRFO2dCQUM1RSxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzNFLENBQUM7aUJBQU0sQ0FBQztnQkFDTiwrQ0FBK0M7Z0JBQy9DLGdGQUFnRjtnQkFDaEYseUVBQXlFO2dCQUN6RSxnRkFBZ0Y7Z0JBQ2hGLHNGQUFzRjtZQUN4RixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCwrRUFBK0U7SUFDL0UsOERBQThEO0lBQzlELCtFQUErRTtJQUMvRSxtRUFBbUU7SUFDbkUsNkRBQTZEO0lBQzdELE1BQU0sZUFBZSxHQUNuQixhQUFhLEtBQUssTUFBTSxJQUFJLGVBQWUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQztRQUNsRixDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FDckMsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDbEIsSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDVixPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsVUFBVSxFQUFFLEVBQUUsYUFBYSxFQUFFLFVBQVUsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNqRixDQUFDO1lBQ0QsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckIsQ0FBQyxDQUFDLENBQ0g7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRWxCLCtFQUErRTtJQUMvRSx1QkFBdUI7SUFDdkIsK0VBQStFO0lBQy9FLE1BQU0sa0JBQWtCLEdBQUcsR0FBdUIsRUFBRTtRQUNsRCxJQUFJLGdCQUFnQjtZQUFFLE9BQU8sZ0JBQWdCLENBQUM7UUFFOUMsNEVBQTRFO1FBQzVFLGtGQUFrRjtRQUNsRix3RkFBd0Y7UUFDeEYsWUFBWSxHQUFHLElBQUksQ0FBQztRQUNwQixtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFL0IsMkNBQTJDO1FBQzNDLDJHQUEyRztRQUMzRywwREFBMEQ7UUFDMUQsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBRXRFLGdCQUFnQixHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQ3JDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQ2Ysb0VBQW9FO1lBQ3BFLDhFQUE4RTtZQUM5RSxNQUFNLFFBQVEsR0FBRyxhQUFhLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFFN0UsSUFBSSxhQUFhLEtBQUssTUFBTSxJQUFJLENBQUMsQ0FBQyxRQUFRLElBQUksUUFBUSxLQUFLLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RFLG9GQUFvRjtnQkFDcEYsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1lBQ2xFLENBQUM7WUFFRCxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLFNBQVMsQ0FBQyxDQUFDO1lBQ2hELE9BQU8sUUFBUSxJQUFJLFNBQVMsQ0FBQztRQUMvQixDQUFDLENBQUMsRUFDRixVQUFVLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNqQixtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFL0IsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRXRDLDhDQUE4QztZQUM5QywyR0FBMkc7WUFDM0csMEZBQTBGO1lBQzFGLElBQUksVUFBVSxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUN2QixzRUFBc0U7Z0JBQ3RFLElBQUksYUFBYSxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUNoQyxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLFVBQVUsSUFBSSxrQkFBa0IsQ0FBQztvQkFDckUsZUFBZSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLENBQUM7Z0JBQ2xELENBQUM7Z0JBRUQsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQzdELFNBQVMsQ0FBQyxHQUFHLEVBQUU7b0JBQ2IsK0NBQStDO29CQUMvQyxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDO29CQUU1QixJQUFJLE1BQU0sQ0FBQyxTQUFTLEVBQUUsY0FBYyxFQUFFLENBQUM7d0JBQ3JDLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFOzRCQUMvRCwyQkFBMkI7d0JBQzdCLENBQUMsQ0FBQyxDQUFDO29CQUNMLENBQUM7b0JBQ0QsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQy9CLENBQUMsQ0FBQyxDQUNILENBQUM7WUFDSixDQUFDO1lBRUQsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsQ0FBQyxDQUFDLEVBQ0YsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUNaLFlBQVksR0FBRyxLQUFLLENBQUM7WUFDckIsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxFQUNGLFdBQVcsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQ2hELENBQUM7UUFFRixPQUFPLGdCQUFnQixDQUFDO0lBQzFCLENBQUMsQ0FBQztJQUVGLCtFQUErRTtJQUMvRSxnRUFBZ0U7SUFDaEUsK0VBQStFO0lBQy9FLG1HQUFtRztJQUNuRyxxRkFBcUY7SUFDckYsSUFBSSxlQUFlLElBQUksWUFBWSxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFDeEQsT0FBTyxnQkFBZ0IsQ0FBQyxJQUFJLENBQzFCLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ2xCLE1BQU0sUUFBUSxHQUFHLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMvRSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELE9BQU8sZUFBZSxDQUFDLElBQUksQ0FDekIsU0FBUyxDQUFDLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FDNUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLElBQUksQ0FDeEIsVUFBVSxDQUFDLENBQUMsS0FBYyxFQUFFLEVBQUU7UUFDNUIsTUFBTSxZQUFZLEdBQ2hCLEtBQUssWUFBWSxpQkFBaUIsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxlQUFlLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRTdHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNsQixPQUFPLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBRUQsZUFBZSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV6QixPQUFPLGtCQUFrQixFQUFFLENBQUMsSUFBSSxDQUM5QixTQUFTLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNsQixNQUFNLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxlQUFlLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkYsZUFBZSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM5QixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FDRixDQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEVycm9yUmVzcG9uc2UsIEh0dHBFdmVudCwgSHR0cEhhbmRsZXJGbiwgSHR0cFJlcXVlc3QgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtcbiAgQmVoYXZpb3JTdWJqZWN0LFxuICBPYnNlcnZhYmxlLFxuICBjYXRjaEVycm9yLFxuICBmaW5hbGl6ZSxcbiAgZnJvbSxcbiAgbWFwLFxuICBvZixcbiAgc2hhcmVSZXBsYXksXG4gIHN3aXRjaE1hcCxcbiAgdGhyb3dFcnJvcixcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgdHlwZSB7IE5BdXRoQ2xpZW50Q29uZmlnIH0gZnJvbSAnQG5hdXRoLXRvb2xraXQvY2xpZW50JztcbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vbmdtb2R1bGUvYXV0aC5zZXJ2aWNlJztcblxuLyoqXG4gKiBTaGFyZWQgaW50ZXJjZXB0b3IgbG9naWMgZm9yIGJvdGg6XG4gKiAtIEZ1bmN0aW9uYWwgaW50ZXJjZXB0b3IgKEFuZ3VsYXIgMTcrIHN0YW5kYWxvbmUpXG4gKiAtIENsYXNzLWJhc2VkIGludGVyY2VwdG9yIChOZ01vZHVsZSBhcHBzKVxuICpcbiAqIFdIWTpcbiAqIC0gS2VlcCBvbmUgaW1wbGVtZW50YXRpb24gZm9yIGNvb2tpZXMgKyBqc29uIG1vZGUgYmVoYXZpb3IuXG4gKiAtIEF2b2lkIGRpdmVyZ2VuY2UgYmV0d2VlbiBzdGFuZGFsb25lIGFuZCBOZ01vZHVsZSBpbnRlZ3JhdGlvbnMuXG4gKi9cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gUmVmcmVzaCBzdGF0ZSBtYW5hZ2VtZW50IChtb2R1bGUtbGV2ZWwpXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5sZXQgaXNSZWZyZXNoaW5nID0gZmFsc2U7XG5jb25zdCByZWZyZXNoVG9rZW5TdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmcgfCBudWxsPihudWxsKTtcbmxldCByZWZyZXNoSW5GbGlnaHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gfCBudWxsID0gbnVsbDtcbmNvbnN0IHJldHJpZWRSZXF1ZXN0cyA9IG5ldyBXZWFrU2V0PEh0dHBSZXF1ZXN0PHVua25vd24+PigpO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBFcnJvciArIGNvb2tpZSBoZWxwZXJzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogU2FmZWx5IGV4dHJhY3QgSFRUUCBzdGF0dXMgY29kZSBmcm9tIGVpdGhlcjpcbiAqIC0gQW5ndWxhciBIdHRwRXJyb3JSZXNwb25zZSAoSHR0cENsaWVudCBjYWxscylcbiAqIC0gU0RLIE5BdXRoQ2xpZW50RXJyb3IgKHRocm93biBieSB0aGUgU0RLJ3MgSHR0cEFkYXB0ZXIpXG4gKi9cbmZ1bmN0aW9uIGdldFN0YXR1c0NvZGUoZXJyb3I6IHVua25vd24pOiBudW1iZXIgfCBudWxsIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UpIHJldHVybiBlcnJvci5zdGF0dXM7XG4gIGlmICh0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnICYmIGVycm9yICE9PSBudWxsICYmICdzdGF0dXNDb2RlJyBpbiBlcnJvcikge1xuICAgIGNvbnN0IHN0YXR1c0NvZGUgPSAoZXJyb3IgYXMgeyBzdGF0dXNDb2RlPzogdW5rbm93biB9KS5zdGF0dXNDb2RlO1xuICAgIHJldHVybiB0eXBlb2Ygc3RhdHVzQ29kZSA9PT0gJ251bWJlcicgPyBzdGF0dXNDb2RlIDogbnVsbDtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBCZXN0LWVmZm9ydCBDU1JGIGNvb2tpZSBjbGVhcmluZyAobm9uLWh0dHBPbmx5KS5cbiAqXG4gKiBXQVJOSU5HOiBUaGlzIGNhbm5vdCBjbGVhciBodHRwT25seSBhdXRoIGNvb2tpZXMgKGFjY2Vzcy9yZWZyZXNoL2RldmljZSkuXG4gKiBUaG9zZSBtdXN0IGJlIGNsZWFyZWQgYnkgdGhlIGJhY2tlbmQgb24gcmVmcmVzaC9sb2dvdXQuXG4gKi9cbmZ1bmN0aW9uIGNsZWFyQ3NyZkNvb2tpZShiYXNlVXJsOiBzdHJpbmcsIGNvb2tpZU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuXG4gIC8vIFdIWTogQ29va2llIGRvbWFpbiBoYW5kbGluZyBkaWZmZXJzIGJldHdlZW4gbG9jYWxob3N0IGFuZCByZWFsIGRvbWFpbnMuXG4gIC8vIFdlIHRyeSB0byBjbGVhciB3aXRoIGFuIGV4cGxpY2l0IGRvbWFpbiAoaWYgYXZhaWxhYmxlKSwgdGhlbiB3aXRob3V0LlxuICB0cnkge1xuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwoYmFzZVVybCk7XG4gICAgZG9jdW1lbnQuY29va2llID0gYCR7Y29va2llTmFtZX09OyBleHBpcmVzPVRodSwgMDEgSmFuIDE5NzAgMDA6MDA6MDAgVVRDOyBwYXRoPS87IGRvbWFpbj0ke3VybC5ob3N0bmFtZX1gO1xuICAgIGRvY3VtZW50LmNvb2tpZSA9IGAke2Nvb2tpZU5hbWV9PTsgZXhwaXJlcz1UaHUsIDAxIEphbiAxOTcwIDAwOjAwOjAwIFVUQzsgcGF0aD0vYDtcbiAgfSBjYXRjaCB7XG4gICAgZG9jdW1lbnQuY29va2llID0gYCR7Y29va2llTmFtZX09OyBleHBpcmVzPVRodSwgMDEgSmFuIDE5NzAgMDA6MDA6MDAgVVRDOyBwYXRoPS9gO1xuICB9XG59XG5cbi8qKlxuICogR2V0IENTUkYgdG9rZW4gZnJvbSBjb29raWUuXG4gKlxuICogQHBhcmFtIGNvb2tpZU5hbWUgLSBOYW1lIG9mIHRoZSBDU1JGIGNvb2tpZSAoZnJvbSBjb25maWcuY3NyZi5jb29raWVOYW1lKVxuICogQHJldHVybnMgQ1NSRiB0b2tlbiB2YWx1ZSBvciBudWxsIGlmIG5vdCBmb3VuZFxuICovXG5mdW5jdGlvbiBnZXRDc3JmVG9rZW4oY29va2llTmFtZTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gbnVsbDtcbiAgLy8gRXNjYXBlIHNwZWNpYWwgcmVnZXggY2hhcmFjdGVycyBpbiBjb29raWUgbmFtZSB0byBwcmV2ZW50IGluamVjdGlvblxuICBjb25zdCBlc2NhcGVkQ29va2llTmFtZSA9IGNvb2tpZU5hbWUucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKTtcbiAgY29uc3QgbWF0Y2ggPSBkb2N1bWVudC5jb29raWUubWF0Y2gobmV3IFJlZ0V4cChgKF58ICkke2VzY2FwZWRDb29raWVOYW1lfT0oW147XSspYCkpO1xuICByZXR1cm4gbWF0Y2ggPyBkZWNvZGVVUklDb21wb25lbnQobWF0Y2hbMl0pIDogbnVsbDtcbn1cblxuLyoqXG4gKiBCdWlsZCByZXRyeSByZXF1ZXN0IHdpdGggYXBwcm9wcmlhdGUgYXV0aC5cbiAqXG4gKiBJbiBjb29raWVzIG1vZGU6IEJyb3dzZXIgYXV0b21hdGljYWxseSBzZW5kcyB1cGRhdGVkIGh0dHBPbmx5IGNvb2tpZXMgKGFjY2Vzcy9yZWZyZXNoIHRva2VucykuXG4gKiBXZSBtdXN0IHJlLXJlYWQgQ1NSRiB0b2tlbiBhZnRlciByZWZyZXNoIHRvIGF2b2lkIHN0YWxlIGhlYWRlcnMuXG4gKlxuICogSW4gSlNPTiBtb2RlOiBDbG9uZXMgdGhlIHJlcXVlc3QgYW5kIGFkZHMgdGhlIG5ldyBCZWFyZXIgdG9rZW4uXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkUmV0cnlSZXF1ZXN0KFxuICBvcmlnaW5hbFJlcTogSHR0cFJlcXVlc3Q8dW5rbm93bj4sXG4gIHRva2VuRGVsaXZlcnk6IHN0cmluZyxcbiAgbmV3VG9rZW4/OiBzdHJpbmcgfCBudWxsLFxuICBjc3JmQ29uZmlnPzogeyBjb29raWVOYW1lPzogc3RyaW5nOyBoZWFkZXJOYW1lPzogc3RyaW5nIH0sXG4pOiBIdHRwUmVxdWVzdDx1bmtub3duPiB7XG4gIGlmICh0b2tlbkRlbGl2ZXJ5ID09PSAnanNvbicgJiYgbmV3VG9rZW4gJiYgbmV3VG9rZW4gIT09ICdzdWNjZXNzJykge1xuICAgIHJldHVybiBvcmlnaW5hbFJlcS5jbG9uZSh7IHNldEhlYWRlcnM6IHsgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke25ld1Rva2VufWAgfSB9KTtcbiAgfVxuXG4gIGlmICh0b2tlbkRlbGl2ZXJ5ID09PSAnY29va2llcycgJiYgWydQT1NUJywgJ1BVVCcsICdQQVRDSCcsICdERUxFVEUnXS5pbmNsdWRlcyhvcmlnaW5hbFJlcS5tZXRob2QpKSB7XG4gICAgY29uc3QgY3NyZkNvb2tpZU5hbWUgPSBjc3JmQ29uZmlnPy5jb29raWVOYW1lID8/ICduYXV0aF9jc3JmX3Rva2VuJztcbiAgICBjb25zdCBjc3JmSGVhZGVyTmFtZSA9IGNzcmZDb25maWc/LmhlYWRlck5hbWUgPz8gJ3gtY3NyZi10b2tlbic7XG4gICAgLy8gQWx3YXlzIHJlZnJlc2ggQ1NSRiB0b2tlbiBvbiByZXRyeSAoZXZlbiBpZiBpdCBleGlzdHMsIGdldCBmcmVzaCBvbmUpXG4gICAgY29uc3QgZnJlc2hDc3JmVG9rZW4gPSBnZXRDc3JmVG9rZW4oY3NyZkNvb2tpZU5hbWUpO1xuICAgIGlmIChmcmVzaENzcmZUb2tlbikge1xuICAgICAgcmV0dXJuIG9yaWdpbmFsUmVxLmNsb25lKHsgc2V0SGVhZGVyczogeyBbY3NyZkhlYWRlck5hbWVdOiBmcmVzaENzcmZUb2tlbiB9IH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvcmlnaW5hbFJlcTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU5BdXRoQXV0aEh0dHBJbnRlcmNlcHRvcihwYXJhbXM6IHtcbiAgY29uZmlnOiBOQXV0aENsaWVudENvbmZpZztcbiAgaHR0cDogSHR0cENsaWVudDtcbiAgYXV0aFNlcnZpY2U6IEF1dGhTZXJ2aWNlO1xuICByb3V0ZXI6IFJvdXRlcjtcbiAgbmV4dDogSHR0cEhhbmRsZXJGbjtcbiAgcmVxOiBIdHRwUmVxdWVzdDx1bmtub3duPjtcbn0pOiBPYnNlcnZhYmxlPEh0dHBFdmVudDx1bmtub3duPj4ge1xuICBjb25zdCB7IGNvbmZpZywgYXV0aFNlcnZpY2UsIHJvdXRlciwgbmV4dCwgcmVxIH0gPSBwYXJhbXM7XG5cbiAgY29uc3QgdG9rZW5EZWxpdmVyeSA9IGNvbmZpZy50b2tlbkRlbGl2ZXJ5O1xuICBjb25zdCBiYXNlVXJsID0gY29uZmlnLmJhc2VVcmw7XG4gIGNvbnN0IGVuZHBvaW50cyA9IGNvbmZpZy5lbmRwb2ludHMgPz8ge307XG4gIGNvbnN0IGF1dGhQYXRoUHJlZml4ID0gY29uZmlnLmF1dGhQYXRoUHJlZml4O1xuXG4gIC8vIEJ1aWxkIHJlZnJlc2ggcGF0aCB3aXRoIGF1dGhQYXRoUHJlZml4IGlmIGNvbmZpZ3VyZWQgKG1hdGNoZXMgY29yZSBjbGllbnQgYnVpbGRVcmwgbG9naWMgZXhhY3RseSlcbiAgLy8gVXNlIGRlZmF1bHQgJy9yZWZyZXNoJyBpZiBlbmRwb2ludHMucmVmcmVzaCBpcyBub3QgZGVmaW5lZFxuICBjb25zdCByZWZyZXNoUGF0aCA9IGVuZHBvaW50cz8ucmVmcmVzaCA/PyAnL3JlZnJlc2gnO1xuICBjb25zdCBub3JtYWxpemVkUmVmcmVzaFBhdGggPSByZWZyZXNoUGF0aC5zdGFydHNXaXRoKCcvJykgPyByZWZyZXNoUGF0aCA6IGAvJHtyZWZyZXNoUGF0aH1gO1xuXG4gIC8vIENoZWNrIGlmIGJhc2VVcmwgYWxyZWFkeSBlbmRzIHdpdGggYXV0aFBhdGhQcmVmaXggdG8gYXZvaWQgZG91YmxlLXByZWZpeGluZ1xuICAvLyBUaGlzIG11c3QgbWF0Y2ggdGhlIGNvcmUgY2xpZW50J3MgYnVpbGRVcmwgbG9naWMgZXhhY3RseVxuICBjb25zdCBiYXNlVXJsRW5kc1dpdGhQcmVmaXggPSBhdXRoUGF0aFByZWZpeCAmJiBiYXNlVXJsLmVuZHNXaXRoKGF1dGhQYXRoUHJlZml4KTtcblxuICBjb25zdCBzaG91bGRBZGRQcmVmaXggPSBhdXRoUGF0aFByZWZpeCAmJiAhYmFzZVVybEVuZHNXaXRoUHJlZml4ICYmICFub3JtYWxpemVkUmVmcmVzaFBhdGguc3RhcnRzV2l0aChhdXRoUGF0aFByZWZpeCk7XG4gIGNvbnN0IGVmZmVjdGl2ZVJlZnJlc2hQYXRoID0gc2hvdWxkQWRkUHJlZml4ID8gYCR7YXV0aFBhdGhQcmVmaXh9JHtub3JtYWxpemVkUmVmcmVzaFBhdGh9YCA6IG5vcm1hbGl6ZWRSZWZyZXNoUGF0aDtcblxuICBjb25zdCBsb2dpblBhdGggPSBlbmRwb2ludHMubG9naW4gPz8gJy9sb2dpbic7XG4gIGNvbnN0IHNpZ251cFBhdGggPSBlbmRwb2ludHMuc2lnbnVwID8/ICcvc2lnbnVwJztcbiAgY29uc3Qgc29jaWFsRXhjaGFuZ2VQYXRoID0gZW5kcG9pbnRzLnNvY2lhbEV4Y2hhbmdlID8/ICcvc29jaWFsL2V4Y2hhbmdlJztcblxuICBjb25zdCBpc0F1dGhBcGlSZXF1ZXN0ID0gcmVxLnVybC5pbmNsdWRlcyhiYXNlVXJsKTtcbiAgLy8gQ2hlY2sgaWYgcmVxdWVzdCBpcyB0byByZWZyZXNoIGVuZHBvaW50ICh1c2luZyBlZmZlY3RpdmUgcGF0aCB3aXRoIGF1dGhQYXRoUHJlZml4KVxuICBjb25zdCBpc1JlZnJlc2hFbmRwb2ludCA9IHJlcS51cmwuaW5jbHVkZXMoZWZmZWN0aXZlUmVmcmVzaFBhdGgpO1xuICBjb25zdCBpc1B1YmxpY0VuZHBvaW50ID1cbiAgICByZXEudXJsLmluY2x1ZGVzKGxvZ2luUGF0aCkgfHwgcmVxLnVybC5pbmNsdWRlcyhzaWdudXBQYXRoKSB8fCByZXEudXJsLmluY2x1ZGVzKHNvY2lhbEV4Y2hhbmdlUGF0aCk7XG4gIGNvbnN0IHNob3VsZEludGVyY2VwdCA9IGlzQXV0aEFwaVJlcXVlc3QgJiYgIWlzUmVmcmVzaEVuZHBvaW50ICYmICFpc1B1YmxpY0VuZHBvaW50O1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gQnVpbGQgcmVxdWVzdCBmb3IgY29va2llcyBtb2RlICh3aXRoQ3JlZGVudGlhbHMgKyBDU1JGKVxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIElNUE9SVEFOVDogV2hlbiB1c2luZyBBbmd1bGFySHR0cEFkYXB0ZXIsIGhlYWRlcnMgZnJvbSBidWlsZEhlYWRlcnMoKSBhcmUgcGFzc2VkXG4gIC8vIHRvIEh0dHBDbGllbnQucmVxdWVzdCgpIGFzIGEgcGxhaW4gb2JqZWN0LiBBbmd1bGFyIGNvbnZlcnRzIHRoZXNlIHRvIEh0dHBIZWFkZXJzXG4gIC8vIGFuZCBjcmVhdGVzIGFuIEh0dHBSZXF1ZXN0LiBIb3dldmVyLCB3ZSBjYW5ub3QgcmVseSBvbiBidWlsZEhlYWRlcnMoKSB0byBhZGQgQ1NSRlxuICAvLyBpbiBBbmd1bGFyIGNvbnRleHQgYmVjYXVzZTpcbiAgLy8gMS4gaGFzV2luZG93KCkgbWlnaHQgcmV0dXJuIGZhbHNlIGluIFNTUiBjb250ZXh0c1xuICAvLyAyLiBIZWFkZXJzIG1pZ2h0IG5vdCBiZSBwcm9wZXJseSBtZXJnZWQgaW50byB0aGUgSHR0cFJlcXVlc3QgdGhhdCBpbnRlcmNlcHRvcnMgcmVjZWl2ZVxuICAvLyAzLiBUaGUgaW50ZXJjZXB0b3IgaXMgdGhlIGF1dGhvcml0YXRpdmUgcGxhY2UgZm9yIENTUkYgaW4gQW5ndWxhciBhcHBzXG4gIC8vXG4gIC8vIFRoZXJlZm9yZSwgdGhlIGludGVyY2VwdG9yIEFMV0FZUyBhZGRzIENTUkYgZm9yIG11dGF0aW5nIG1ldGhvZHMgaW4gY29va2llcyBtb2RlLFxuICAvLyByZWdhcmRsZXNzIG9mIHdoZXRoZXIgYnVpbGRIZWFkZXJzKCkgYWRkZWQgaXQgKGZvciB2YW5pbGxhIGNsaWVudHMpLlxuICBsZXQgYXV0aFJlcSA9IHJlcTtcbiAgaWYgKHRva2VuRGVsaXZlcnkgPT09ICdjb29raWVzJykge1xuICAgIGF1dGhSZXEgPSBhdXRoUmVxLmNsb25lKHsgd2l0aENyZWRlbnRpYWxzOiB0cnVlIH0pO1xuICAgIC8vIEFkZCBDU1JGIHRva2VuIGZvciBtdXRhdGluZyBtZXRob2RzIChQT1NULCBQVVQsIFBBVENILCBERUxFVEUpXG4gICAgLy8gQWx3YXlzIGFkZCBpdCBoZXJlIC0gZG9uJ3QgcmVseSBvbiBidWlsZEhlYWRlcnMoKSBpbiBBbmd1bGFyIGNvbnRleHRcbiAgICAvLyBBZGQgQ1NSRiB0b2tlbiBmb3IgbXV0YXRpbmcgbWV0aG9kcyAoUE9TVCwgUFVULCBQQVRDSCwgREVMRVRFKVxuICAgIC8vIFRoaXMgcnVucyBmb3IgQUxMIHJlcXVlc3RzIGluIGNvb2tpZXMgbW9kZSwgbm90IGp1c3QgYXV0aCBBUEkgcmVxdWVzdHNcbiAgICAvLyBUaGlzIGVuc3VyZXMgQ1NSRiBwcm90ZWN0aW9uIGZvciBhbGwgbXV0YXRpbmcgb3BlcmF0aW9uc1xuICAgIGlmIChbJ1BPU1QnLCAnUFVUJywgJ1BBVENIJywgJ0RFTEVURSddLmluY2x1ZGVzKHJlcS5tZXRob2QpKSB7XG4gICAgICAvLyBSZXNwZWN0IHVzZXIncyBDU1JGIGNvbmZpZywgZmFsbGJhY2sgdG8gZGVmYXVsdHMgaWYgbm90IHByb3ZpZGVkXG4gICAgICAvLyBUaGVzZSBkZWZhdWx0cyBtdXN0IG1hdGNoIHRoZSBiYWNrZW5kJ3MgQ1NSRiBjb25maWd1cmF0aW9uXG4gICAgICBjb25zdCBjc3JmQ29va2llTmFtZSA9IGNvbmZpZy5jc3JmPy5jb29raWVOYW1lID8/ICduYXV0aF9jc3JmX3Rva2VuJztcbiAgICAgIGNvbnN0IGNzcmZIZWFkZXJOYW1lID0gY29uZmlnLmNzcmY/LmhlYWRlck5hbWUgPz8gJ3gtY3NyZi10b2tlbic7XG5cbiAgICAgIC8vIEdldCBDU1JGIHRva2VuIGZyb20gY29va2llIHVzaW5nIHRoZSBjb25maWd1cmVkIGNvb2tpZSBuYW1lXG4gICAgICBjb25zdCBjc3JmVG9rZW4gPSBnZXRDc3JmVG9rZW4oY3NyZkNvb2tpZU5hbWUpO1xuXG4gICAgICBpZiAoY3NyZlRva2VuKSB7XG4gICAgICAgIC8vIFVzZSBzZXRIZWFkZXJzIHdoaWNoIHdpbGwgb3ZlcnJpZGUgaWYgYWxyZWFkeSBleGlzdHMgKGZyb20gYnVpbGRIZWFkZXJzKVxuICAgICAgICAvLyBUaGlzIGVuc3VyZXMgQ1NSRiBpcyBhbHdheXMgcHJlc2VudCBmb3IgREVMRVRFIGFuZCBvdGhlciBtdXRhdGluZyBtZXRob2RzXG4gICAgICAgIGF1dGhSZXEgPSBhdXRoUmVxLmNsb25lKHsgc2V0SGVhZGVyczogeyBbY3NyZkhlYWRlck5hbWVdOiBjc3JmVG9rZW4gfSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIENTUkYgdG9rZW4gbm90IGZvdW5kIC0gdGhpcyBjb3VsZCBoYXBwZW4gaWY6XG4gICAgICAgIC8vIDEuIENvb2tpZSBkb2Vzbid0IGV4aXN0IChiZWZvcmUgZmlyc3QgbG9naW4sIGFmdGVyIGxvZ291dCwgb3IgY29va2llIGV4cGlyZWQpXG4gICAgICAgIC8vIDIuIENvb2tpZSBuYW1lIG1pc21hdGNoIChjaGVjayBjb25maWcuY3NyZi5jb29raWVOYW1lIG1hdGNoZXMgYmFja2VuZClcbiAgICAgICAgLy8gMy4gQ29va2llIGlzIGh0dHBPbmx5IGFuZCBjYW4ndCBiZSByZWFkIChidXQgQ1NSRiBjb29raWVzIHNob3VsZCBiZSByZWFkYWJsZSlcbiAgICAgICAgLy8gVGhlIGJhY2tlbmQgc2hvdWxkIGhhbmRsZSBtaXNzaW5nIENTUkYgdG9rZW5zIGFwcHJvcHJpYXRlbHkgKHJldHVybiA0MDMgb3Igc2ltaWxhcilcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEpTT04gbW9kZTogYXR0YWNoIEF1dGhvcml6YXRpb24gaGVhZGVyIGZvciBIdHRwQ2xpZW50IGNhbGxzXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gU2ltcGxlIGFwcHJvYWNoOiBhdHRhY2ggdG9rZW4gaWYgYXZhaWxhYmxlLCBsZXQgYmFja2VuZCB2YWxpZGF0ZVxuICAvLyBIYW5kbGUgNDAxIHJlYWN0aXZlbHkgKG1hdGNoZXMgb2xkIHdvcmtpbmcgaW1wbGVtZW50YXRpb24pXG4gIGNvbnN0IGF0dGFjaEpzb25BdXRoJCA9XG4gICAgdG9rZW5EZWxpdmVyeSA9PT0gJ2pzb24nICYmIHNob3VsZEludGVyY2VwdCAmJiAhYXV0aFJlcS5oZWFkZXJzLmhhcygnQXV0aG9yaXphdGlvbicpXG4gICAgICA/IGZyb20oYXV0aFNlcnZpY2UuZ2V0QWNjZXNzVG9rZW4oKSkucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKHRva2VuKSA9PiB7XG4gICAgICAgICAgICBpZiAodG9rZW4pIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG9mKGF1dGhSZXEuY2xvbmUoeyBzZXRIZWFkZXJzOiB7IEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHt0b2tlbn1gIH0gfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9mKGF1dGhSZXEpO1xuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICA6IG9mKGF1dGhSZXEpO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gUmVmcmVzaCBjb29yZGluYXRpb25cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBjb25zdCBnZXRPclN0YXJ0UmVmcmVzaCQgPSAoKTogT2JzZXJ2YWJsZTxzdHJpbmc+ID0+IHtcbiAgICBpZiAocmVmcmVzaEluRmxpZ2h0JCkgcmV0dXJuIHJlZnJlc2hJbkZsaWdodCQ7XG5cbiAgICAvLyBXSFk6IFdlIHdhbnQgdG8gZW5zdXJlIG9ubHkgb25lIHJlZnJlc2ggcmVxdWVzdCBpcyBpbiBmbGlnaHQgYXQgYW55IHRpbWUuXG4gICAgLy8gQWxsIHJlcXVlc3RzIChpbmNsdWRpbmcgdGhvc2UgdGhhdCBoYXZlbid0IGhpdCB0aGUgYmFja2VuZCB5ZXQpIHNob3VsZCB3YWl0IGZvclxuICAgIC8vIHRoZSBzYW1lIHJlZnJlc2ggcmVzdWx0IHRvIGF2b2lkIGEgYnVyc3Qgb2YgNDAxcyBhbmQgcG90ZW50aWFsIFdBRi9yYXRlLWxpbWl0IGlzc3Vlcy5cbiAgICBpc1JlZnJlc2hpbmcgPSB0cnVlO1xuICAgIHJlZnJlc2hUb2tlblN1YmplY3QubmV4dChudWxsKTtcblxuICAgIC8vIFdIWTogQWx3YXlzIHJlZnJlc2ggdmlhIHRoZSBjb3JlIGNsaWVudC5cbiAgICAvLyAtIEVuc3VyZXMgYXV0aFBhdGhQcmVmaXggKyBkZWZhdWx0IGVuZHBvaW50cyBhcmUgYXBwbGllZCBjb25zaXN0ZW50bHkgKGZpeGVzIC9yZWZyZXNoIHZzIC9hdXRoL3JlZnJlc2gpLlxuICAgIC8vIC0gQ2VudHJhbGl6ZXMgQ1NSRiArIGNyZWRlbnRpYWxzIGhhbmRsaW5nIGluIG9uZSBwbGFjZS5cbiAgICBjb25zdCByZWZyZXNoUmVxdWVzdCQgPSBmcm9tKGF1dGhTZXJ2aWNlLmdldENsaWVudCgpLnJlZnJlc2hUb2tlbnMoKSk7XG5cbiAgICByZWZyZXNoSW5GbGlnaHQkID0gcmVmcmVzaFJlcXVlc3QkLnBpcGUoXG4gICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgIC8vIENvb2tpZXMgbW9kZTogc3VjY2VzcyBpcyBlbm91Z2ggKHRva2VucyBhcmUgaW4gaHR0cE9ubHkgY29va2llcykuXG4gICAgICAgIC8vIEpTT04gbW9kZTogd2UgbmVlZCB0aGUgbmV3IGFjY2VzcyB0b2tlbiB0byByZXRyeSArIHVuYmxvY2sgcXVldWVkIHJlcXVlc3RzLlxuICAgICAgICBjb25zdCBuZXdUb2tlbiA9IHRva2VuRGVsaXZlcnkgPT09ICdqc29uJyA/IHJlc3BvbnNlLmFjY2Vzc1Rva2VuIDogJ3N1Y2Nlc3MnO1xuXG4gICAgICAgIGlmICh0b2tlbkRlbGl2ZXJ5ID09PSAnanNvbicgJiYgKCFuZXdUb2tlbiB8fCBuZXdUb2tlbiA9PT0gJ3N1Y2Nlc3MnKSkge1xuICAgICAgICAgIC8vIOKaoO+4jyBXQVJOSU5HOiBXaXRob3V0IGFuIGFjY2VzcyB0b2tlbiB3ZSBjYW5ub3Qgc2FmZWx5IHJldHJ5IHJlcXVlc3RzIGluIEpTT04gbW9kZS5cbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Rva2VuIHJlZnJlc2ggZGlkIG5vdCByZXR1cm4gYW4gYWNjZXNzIHRva2VuJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZWZyZXNoVG9rZW5TdWJqZWN0Lm5leHQobmV3VG9rZW4gPz8gJ3N1Y2Nlc3MnKTtcbiAgICAgICAgcmV0dXJuIG5ld1Rva2VuID8/ICdzdWNjZXNzJztcbiAgICAgIH0pLFxuICAgICAgY2F0Y2hFcnJvcigoZXJyKSA9PiB7XG4gICAgICAgIHJlZnJlc2hUb2tlblN1YmplY3QubmV4dChudWxsKTtcblxuICAgICAgICBjb25zdCBzdGF0dXNDb2RlID0gZ2V0U3RhdHVzQ29kZShlcnIpO1xuXG4gICAgICAgIC8vIFJlZnJlc2ggZmFpbGVkIHdpdGggNDAxID0+IHNlc3Npb24gZXhwaXJlZC5cbiAgICAgICAgLy8gQ2xlYXIgKmxvY2FsKiBTREsgc3RhdGUgc28gZ3VhcmRzL3BhZ2VzIGRvbid0IHRoaW5rIHRoZSB1c2VyIGlzIHN0aWxsIGxvZ2dlZCBpbiBhZnRlciBuYXZpZ2F0aW9uL3JlbG9hZC5cbiAgICAgICAgLy8gSU1QT1JUQU5UOiBUaGlzIGFsc28gY2xlYXJzIGNoYWxsZW5nZSBzZXNzaW9ucyBhbmQgT0F1dGggc3RhdGUgdG8gcHJldmVudCBnaG9zdCBzdGF0ZXMuXG4gICAgICAgIGlmIChzdGF0dXNDb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAvLyBCZXN0LWVmZm9ydDogYWxzbyBjbGVhciBDU1JGIGNvb2tpZSBpbiBjb29raWVzIG1vZGUgKG5vbi1odHRwT25seSkuXG4gICAgICAgICAgaWYgKHRva2VuRGVsaXZlcnkgPT09ICdjb29raWVzJykge1xuICAgICAgICAgICAgY29uc3QgY3NyZkNvb2tpZU5hbWUgPSBjb25maWcuY3NyZj8uY29va2llTmFtZSA/PyAnbmF1dGhfY3NyZl90b2tlbic7XG4gICAgICAgICAgICBjbGVhckNzcmZDb29raWUoY29uZmlnLmJhc2VVcmwsIGNzcmZDb29raWVOYW1lKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZnJvbShhdXRoU2VydmljZS5nZXRDbGllbnQoKS5jbGVhckxvY2FsQXV0aFN0YXRlKCkpLnBpcGUoXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAvLyBDYWxsIG9uU2Vzc2lvbkV4cGlyZWQgY2FsbGJhY2sgaWYgY29uZmlndXJlZFxuICAgICAgICAgICAgICBjb25maWcub25TZXNzaW9uRXhwaXJlZD8uKCk7XG5cbiAgICAgICAgICAgICAgaWYgKGNvbmZpZy5yZWRpcmVjdHM/LnNlc3Npb25FeHBpcmVkKSB7XG4gICAgICAgICAgICAgICAgcm91dGVyLm5hdmlnYXRlQnlVcmwoY29uZmlnLnJlZGlyZWN0cy5zZXNzaW9uRXhwaXJlZCkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIG5hdmlnYXRpb24gZXJyb3JzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnIpO1xuICAgICAgfSksXG4gICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgIGlzUmVmcmVzaGluZyA9IGZhbHNlO1xuICAgICAgICByZWZyZXNoSW5GbGlnaHQkID0gbnVsbDtcbiAgICAgIH0pLFxuICAgICAgc2hhcmVSZXBsYXkoeyBidWZmZXJTaXplOiAxLCByZWZDb3VudDogZmFsc2UgfSksXG4gICAgKTtcblxuICAgIHJldHVybiByZWZyZXNoSW5GbGlnaHQkO1xuICB9O1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gUHJlLXJlcXVlc3QgZ2F0aW5nOiBibG9jayByZXF1ZXN0cyB3aGlsZSByZWZyZXNoIGlzIGluLWZsaWdodFxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFdIWTogUHJldmVudCBtdWx0aXBsZSByZXF1ZXN0cyBmcm9tIGhpdHRpbmcgdGhlIGJhY2tlbmQgd2l0aCBhbiBleHBpcmVkIHRva2VuIGFuZCByZXR1cm5pbmcgNDAxLlxuICAvLyBXZSBxdWV1ZSBhbGwgYXV0aCBBUEkgY2FsbHMgZHVyaW5nIHJlZnJlc2ggYW5kIHJlbGVhc2UgdGhlbSBvbmNlIHJlZnJlc2ggc3VjY2VlZHMuXG4gIGlmIChzaG91bGRJbnRlcmNlcHQgJiYgaXNSZWZyZXNoaW5nICYmIHJlZnJlc2hJbkZsaWdodCQpIHtcbiAgICByZXR1cm4gcmVmcmVzaEluRmxpZ2h0JC5waXBlKFxuICAgICAgc3dpdGNoTWFwKCh0b2tlbikgPT4ge1xuICAgICAgICBjb25zdCBnYXRlZFJlcSA9IGJ1aWxkUmV0cnlSZXF1ZXN0KGF1dGhSZXEsIHRva2VuRGVsaXZlcnksIHRva2VuLCBjb25maWcuY3NyZik7XG4gICAgICAgIHJldHVybiBuZXh0KGdhdGVkUmVxKTtcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gYXR0YWNoSnNvbkF1dGgkLnBpcGUoXG4gICAgc3dpdGNoTWFwKChyZXF1ZXN0V2l0aEF1dGgpID0+XG4gICAgICBuZXh0KHJlcXVlc3RXaXRoQXV0aCkucGlwZShcbiAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgICBjb25zdCBzaG91bGRIYW5kbGUgPVxuICAgICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSAmJiBlcnJvci5zdGF0dXMgPT09IDQwMSAmJiBzaG91bGRJbnRlcmNlcHQgJiYgIXJldHJpZWRSZXF1ZXN0cy5oYXMocmVxKTtcblxuICAgICAgICAgIGlmICghc2hvdWxkSGFuZGxlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0cmllZFJlcXVlc3RzLmFkZChyZXEpO1xuXG4gICAgICAgICAgcmV0dXJuIGdldE9yU3RhcnRSZWZyZXNoJCgpLnBpcGUoXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKHRva2VuKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHJldHJ5UmVxID0gYnVpbGRSZXRyeVJlcXVlc3QocmVxdWVzdFdpdGhBdXRoLCB0b2tlbkRlbGl2ZXJ5LCB0b2tlbiwgY29uZmlnLmNzcmYpO1xuICAgICAgICAgICAgICByZXRyaWVkUmVxdWVzdHMuYWRkKHJldHJ5UmVxKTtcbiAgICAgICAgICAgICAgcmV0dXJuIG5leHQocmV0cnlSZXEpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgICksXG4gICk7XG59XG4iXX0=
|
|
@@ -1688,6 +1688,7 @@ function createNAuthAuthHttpInterceptor(params) {
|
|
|
1688
1688
|
const statusCode = getStatusCode(err);
|
|
1689
1689
|
// Refresh failed with 401 => session expired.
|
|
1690
1690
|
// Clear *local* SDK state so guards/pages don't think the user is still logged in after navigation/reload.
|
|
1691
|
+
// IMPORTANT: This also clears challenge sessions and OAuth state to prevent ghost states.
|
|
1691
1692
|
if (statusCode === 401) {
|
|
1692
1693
|
// Best-effort: also clear CSRF cookie in cookies mode (non-httpOnly).
|
|
1693
1694
|
if (tokenDelivery === 'cookies') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nauth-toolkit-client-angular.mjs","sources":["../../src/ngmodule/tokens.ts","../../src/ngmodule/http-adapter.ts","../../src/lib/recaptcha.service.ts","../../src/ngmodule/auth.service.ts","../../src/lib/auth-interceptor.shared.ts","../../src/ngmodule/auth.interceptor.class.ts","../../src/lib/auth.guard.ts","../../src/ngmodule/nauth.module.ts","../../src/lib/auth.interceptor.ts","../../src/lib/social-redirect-callback.guard.ts","../../src/lib/recaptcha-provider.ts","../../src/public-api.ts","../../src/nauth-toolkit-client-angular.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { NAuthClientConfig } from '@nauth-toolkit/client';\n\n/**\n * reCAPTCHA configuration for Angular client.\n *\n * Extends base client RecaptchaConfig with Angular-specific options.\n *\n * @example v3 Automatic Mode\n * ```typescript\n * {\n * enabled: true,\n * version: 'v3',\n * siteKey: '6LcExample_Site_Key',\n * action: 'login',\n * autoLoadScript: true,\n * }\n * ```\n *\n * @example v2 Manual Mode\n * ```typescript\n * {\n * enabled: true,\n * version: 'v2',\n * siteKey: '6LcExample_Site_Key',\n * manualChallenge: true,\n * }\n * ```\n */\nexport interface RecaptchaAngularConfig {\n /**\n * Enable/disable reCAPTCHA.\n * Set to false to disable even if configured (useful for testing).\n */\n enabled: boolean;\n\n /**\n * reCAPTCHA version: v2 (checkbox), v3 (invisible), or enterprise.\n */\n version: 'v2' | 'v3' | 'enterprise';\n\n /**\n * Site key from Google reCAPTCHA console.\n * This is safe to expose publicly (it's the public key).\n */\n siteKey: string;\n\n /**\n * Action name for v3/Enterprise analytics.\n * Helps track which actions are being protected.\n * Common values: 'login', 'signup', 'submit'\n *\n * @default 'submit'\n */\n action?: string;\n\n /**\n * Manual challenge mode (v2 only).\n * If true, you must manually call RecaptchaService.render() and get token.\n * If false, AuthService auto-generates token before login/signup.\n *\n * @default false\n */\n manualChallenge?: boolean;\n\n /**\n * Automatically load the Google reCAPTCHA script.\n * If false, you must manually load the script.\n *\n * @default true\n */\n autoLoadScript?: boolean;\n\n /**\n * Language code for reCAPTCHA widget (v2 only).\n * @example 'en', 'es', 'fr', 'de'\n * @default Browser language\n */\n language?: string;\n}\n\n/**\n * Angular-specific NAuth configuration.\n *\n * Extends base NAuthClientConfig with Angular-specific options.\n *\n * @example\n * ```typescript\n * const config: NAuthAngularConfig = {\n * baseUrl: 'https://api.example.com/auth',\n * tokenDelivery: 'cookies',\n * recaptcha: {\n * enabled: true,\n * version: 'v3',\n * siteKey: '6LcExample_Site_Key',\n * action: 'login',\n * },\n * };\n * ```\n */\nexport interface NAuthAngularConfig extends NAuthClientConfig {\n /**\n * Google reCAPTCHA configuration (optional).\n * Provides bot protection for login/signup endpoints.\n */\n recaptcha?: RecaptchaAngularConfig;\n}\n\n/**\n * Injection token for providing NAuthClientConfig in Angular apps.\n */\nexport const NAUTH_CLIENT_CONFIG = new InjectionToken<NAuthClientConfig>('NAUTH_CLIENT_CONFIG');\n","import { Injectable } from '@angular/core';\nimport { HttpClient, HttpErrorResponse } from '@angular/common/http';\nimport { firstValueFrom } from 'rxjs';\nimport { HttpAdapter, HttpRequest, HttpResponse, NAuthClientError, NAuthErrorCode } from '@nauth-toolkit/client';\n\n/**\n * HTTP adapter for Angular using HttpClient.\n *\n * This adapter:\n * - Uses Angular's HttpClient for all requests\n * - Works with Angular's HTTP interceptors (including authInterceptor)\n * - Auto-provided via Angular DI (providedIn: 'root')\n * - Converts HttpClient responses to HttpResponse format\n * - Converts HttpErrorResponse to NAuthClientError\n *\n * Users don't need to configure this manually - it's automatically\n * injected when using AuthService in Angular apps.\n *\n * @example\n * ```typescript\n * // Automatic usage (no manual setup needed)\n * // AuthService automatically injects AngularHttpAdapter\n * constructor(private auth: AuthService) {}\n * ```\n */\n@Injectable()\nexport class AngularHttpAdapter implements HttpAdapter {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Safely parse a JSON response body.\n *\n * Angular's fetch backend (`withFetch()`) will throw a raw `SyntaxError` if\n * `responseType: 'json'` is used and the backend returns HTML (common for\n * proxies, 502 pages, SSR fallbacks, or misrouted requests).\n *\n * To avoid crashing consumer apps, we always request as text and then parse\n * JSON only when the response actually looks like JSON.\n *\n * @param bodyText - Raw response body as text\n * @param contentType - Content-Type header value (if available)\n * @returns Parsed JSON value (unknown)\n * @throws {SyntaxError} When body is non-empty but not valid JSON\n */\n private parseJsonBody(bodyText: string, contentType: string | null): unknown {\n const trimmed = bodyText.trim();\n if (!trimmed) return null;\n\n // If it's clearly HTML, never attempt JSON.parse (some proxies mislabel Content-Type).\n if (trimmed.startsWith('<')) {\n return bodyText;\n }\n\n const looksLikeJson = trimmed.startsWith('{') || trimmed.startsWith('[');\n const isJsonContentType = typeof contentType === 'string' && contentType.toLowerCase().includes('application/json');\n\n if (!looksLikeJson && !isJsonContentType) {\n // Return raw text when it doesn't look like JSON (e.g., HTML error pages).\n return bodyText;\n }\n\n return JSON.parse(trimmed) as unknown;\n }\n\n /**\n * Execute HTTP request using Angular's HttpClient.\n *\n * @param config - Request configuration\n * @returns Response with parsed data\n * @throws NAuthClientError if request fails\n */\n async request<T>(config: HttpRequest): Promise<HttpResponse<T>> {\n try {\n // Use Angular's HttpClient - goes through ALL interceptors.\n // IMPORTANT: Use responseType 'text' to avoid raw JSON.parse crashes when\n // the backend returns HTML (seen in some proxy/SSR/misroute setups).\n const res = await firstValueFrom(\n this.http.request(config.method, config.url, {\n body: config.body,\n headers: config.headers,\n withCredentials: config.credentials === 'include',\n observe: 'response',\n responseType: 'text',\n }),\n );\n\n const contentType = res.headers?.get('content-type');\n const parsed = this.parseJsonBody(res.body ?? '', contentType);\n\n return {\n data: parsed as T,\n status: res.status,\n headers: {}, // Reserved for future header passthrough if needed\n };\n } catch (error) {\n if (error instanceof HttpErrorResponse) {\n // Convert Angular's HttpErrorResponse to NAuthClientError.\n // When using responseType 'text', `error.error` is typically a string.\n const contentType = error.headers?.get('content-type') ?? null;\n const rawBody = typeof error.error === 'string' ? error.error : '';\n const parsedError = this.parseJsonBody(rawBody, contentType);\n\n const errorData =\n typeof parsedError === 'object' && parsedError !== null ? (parsedError as Record<string, unknown>) : {};\n const code =\n typeof errorData['code'] === 'string' ? (errorData['code'] as NAuthErrorCode) : NAuthErrorCode.INTERNAL_ERROR;\n const message =\n typeof errorData['message'] === 'string'\n ? (errorData['message'] as string)\n : typeof parsedError === 'string' && parsedError.trim()\n ? parsedError\n : error.message || `Request failed with status ${error.status}`;\n const timestamp = typeof errorData['timestamp'] === 'string' ? (errorData['timestamp'] as string) : undefined;\n const details =\n typeof errorData['details'] === 'object' ? (errorData['details'] as Record<string, unknown>) : undefined;\n\n throw new NAuthClientError(code, message, {\n statusCode: error.status,\n timestamp,\n details,\n isNetworkError: error.status === 0, // Network error (no response from server)\n });\n }\n\n // Re-throw non-HTTP errors as an SDK error so consumers don't see raw parser crashes.\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new NAuthClientError(NAuthErrorCode.INTERNAL_ERROR, message, {\n statusCode: 0,\n isNetworkError: true,\n });\n }\n }\n}\n","import { Injectable, Inject, PLATFORM_ID, Optional, InjectionToken } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n\n/**\n * Detects the current platform environment\n */\ntype Platform = 'web' | 'capacitor-webview' | 'capacitor-native' | 'ssr';\n\n/**\n * reCAPTCHA version type\n */\ntype RecaptchaVersion = 'v2' | 'v3' | 'enterprise';\n\n/**\n * reCAPTCHA configuration for RecaptchaService\n * \n * Internal configuration interface used by RecaptchaService.\n * Use RecaptchaAngularConfig from tokens.ts for app configuration.\n */\nexport interface RecaptchaServiceConfig {\n enabled: boolean;\n version: RecaptchaVersion;\n siteKey: string;\n action?: string;\n autoLoadScript?: boolean;\n language?: string;\n}\n\n/**\n * Injection token for reCAPTCHA configuration\n */\nexport const RECAPTCHA_CONFIG = new InjectionToken<RecaptchaServiceConfig | undefined>('RECAPTCHA_CONFIG', {\n providedIn: 'root',\n factory: () => undefined,\n});\n\n/**\n * Google reCAPTCHA service for Angular applications.\n *\n * Provides lazy loading of reCAPTCHA script and platform-aware token generation.\n * Automatically detects platform (web, Capacitor WebView, Capacitor native, SSR)\n * and skips reCAPTCHA in environments where it's not supported or needed.\n *\n * Features:\n * - Lazy script loading (only loads when needed)\n * - v2 (checkbox) and v3 (invisible) support\n * - Platform detection (web, Capacitor, SSR)\n * - Automatic skip for Capacitor native mode\n * - Automatic skip for SSR\n *\n * @example v3 Automatic Mode\n * ```typescript\n * constructor(private recaptcha: RecaptchaService) {}\n *\n * async login() {\n * const token = await this.recaptcha.execute('login');\n * await this.auth.login(email, password, token);\n * }\n * ```\n *\n * @example v2 Manual Mode\n * ```typescript\n * ngOnInit() {\n * this.recaptcha.render('recaptcha-container', (token) => {\n * this.recaptchaToken = token;\n * });\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class RecaptchaService {\n private scriptLoaded = false;\n private scriptLoading: Promise<void> | null = null;\n private platform: Platform;\n private widgetId: number | null = null;\n\n constructor(\n @Inject(PLATFORM_ID) private platformId: string,\n @Optional() @Inject(RECAPTCHA_CONFIG) private config?: RecaptchaServiceConfig,\n ) {\n this.platform = this.detectPlatform();\n \n // Auto-preload script for v3/Enterprise so it's ready before first login/signup\n // No-op when disabled, shouldSkip, or v2 (v2 renders on-demand)\n if (this.config?.enabled && (this.config.version === 'v3' || this.config.version === 'enterprise')) {\n if (!this.shouldSkip()) {\n this.loadScript().catch(() => {\n // Silently fail - execute() will handle errors when called\n });\n }\n }\n }\n\n // ============================================================================\n // Platform Detection\n // ============================================================================\n\n /**\n * Detect the current platform environment.\n *\n * Detection priority:\n * 1. SSR (not in browser) → 'ssr'\n * 2. Capacitor native (no web view) → 'capacitor-native'\n * 3. Capacitor WebView → 'capacitor-webview'\n * 4. Web browser → 'web'\n *\n * @returns Detected platform type\n *\n * @example\n * ```typescript\n * const platform = this.detectPlatform();\n * if (platform === 'capacitor-native') {\n * // Skip reCAPTCHA, use device attestation\n * }\n * ```\n */\n private detectPlatform(): Platform {\n // SSR detection\n if (!isPlatformBrowser(this.platformId)) {\n return 'ssr';\n }\n\n // Capacitor detection (window.Capacitor exists)\n const windowRef = window as { Capacitor?: { isNativePlatform?: () => boolean } };\n\n if (windowRef.Capacitor) {\n // Capacitor native (iOS/Android app)\n if (typeof windowRef.Capacitor.isNativePlatform === 'function' && windowRef.Capacitor.isNativePlatform()) {\n return 'capacitor-native';\n }\n // Capacitor WebView\n return 'capacitor-webview';\n }\n\n return 'web';\n }\n\n /**\n * Get the current platform.\n *\n * @returns Current platform type\n */\n getPlatform(): Platform {\n return this.platform;\n }\n\n /**\n * Check if reCAPTCHA should be skipped for current platform.\n *\n * Skips for:\n * - SSR (no window object)\n * - Capacitor native (use device attestation instead)\n *\n * @returns True if should skip reCAPTCHA\n */\n shouldSkip(): boolean {\n return this.platform === 'ssr' || this.platform === 'capacitor-native';\n }\n\n // ============================================================================\n // Script Loading\n // ============================================================================\n\n /**\n * Load Google reCAPTCHA script if not already loaded.\n *\n * Script URL format:\n * - v2: https://www.google.com/recaptcha/api.js\n * - v3: https://www.google.com/recaptcha/api.js?render={siteKey}\n * - Enterprise: https://www.google.com/recaptcha/enterprise.js?render={siteKey}\n *\n * @returns Promise that resolves when script is loaded\n *\n * @throws Error if config is missing or script fails to load\n */\n async loadScript(): Promise<void> {\n // Skip in SSR or Capacitor native\n if (this.shouldSkip()) {\n return;\n }\n\n // Skip if disabled\n if (!this.config?.enabled) {\n return;\n }\n\n // Already loaded\n if (this.scriptLoaded) {\n return;\n }\n\n // Already loading (return existing promise)\n if (this.scriptLoading) {\n return this.scriptLoading;\n }\n\n // Validate config\n if (!this.config.siteKey) {\n throw new Error('[RecaptchaService] Site key is required');\n }\n\n // Start loading\n this.scriptLoading = this.injectScript();\n\n try {\n await this.scriptLoading;\n this.scriptLoaded = true;\n } finally {\n this.scriptLoading = null;\n }\n }\n\n /**\n * Inject the reCAPTCHA script into the DOM.\n *\n * @returns Promise that resolves when script loads\n */\n private injectScript(): Promise<void> {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.async = true;\n script.defer = true;\n\n // Set script URL based on version\n if (this.config!.version === 'enterprise') {\n script.src = `https://www.google.com/recaptcha/enterprise.js?render=${this.config!.siteKey}`;\n } else if (this.config!.version === 'v3') {\n script.src = `https://www.google.com/recaptcha/api.js?render=${this.config!.siteKey}`;\n } else {\n // v2 - load without render parameter\n let url = 'https://www.google.com/recaptcha/api.js';\n if (this.config!.language) {\n url += `?hl=${this.config!.language}`;\n }\n script.src = url;\n }\n\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('[RecaptchaService] Failed to load reCAPTCHA script'));\n\n document.head.appendChild(script);\n });\n }\n\n // ============================================================================\n // v3/Enterprise Methods (Invisible Challenge)\n // ============================================================================\n\n /**\n * Execute reCAPTCHA v3/Enterprise challenge (invisible).\n *\n * Automatically loads script if needed and generates a token.\n * Skips automatically for SSR and Capacitor native.\n *\n * @param action - Action name for v3 analytics (e.g., 'login', 'signup')\n * @returns Promise resolving to reCAPTCHA token, or undefined if skipped\n *\n * @throws Error if version is v2, config missing, or execution fails\n *\n * @example\n * ```typescript\n * const token = await this.recaptcha.execute('login');\n * if (token) {\n * await this.auth.login(email, password, token);\n * }\n * ```\n */\n async execute(action?: string): Promise<string | undefined> {\n // Skip for platforms that don't support reCAPTCHA\n if (this.shouldSkip()) {\n return undefined;\n }\n\n // Skip if disabled\n if (!this.config?.enabled) {\n return undefined;\n }\n\n // v2 requires manual render\n if (this.config.version === 'v2') {\n throw new Error('[RecaptchaService] execute() is only for v3/Enterprise. Use render() for v2.');\n }\n\n // Load script if needed\n await this.loadScript();\n\n // Get grecaptcha object\n const grecaptcha = (window as { grecaptcha?: { execute?: (siteKey: string, options: { action: string }) => Promise<string>; enterprise?: { execute?: (siteKey: string, options: { action: string }) => Promise<string> } } }).grecaptcha;\n\n if (!grecaptcha) {\n throw new Error('[RecaptchaService] grecaptcha is not loaded');\n }\n\n // Execute reCAPTCHA\n const actionName = action || this.config.action || 'submit';\n\n try {\n if (this.config.version === 'enterprise' && grecaptcha.enterprise?.execute) {\n return await grecaptcha.enterprise.execute(this.config.siteKey, { action: actionName });\n } else if (grecaptcha.execute) {\n return await grecaptcha.execute(this.config.siteKey, { action: actionName });\n } else {\n throw new Error('[RecaptchaService] grecaptcha.execute is not available');\n }\n } catch (error: unknown) {\n throw new Error(`[RecaptchaService] Failed to execute reCAPTCHA: ${error instanceof Error ? error.message : 'unknown error'}`);\n }\n }\n\n // ============================================================================\n // v2 Methods (Visible Checkbox)\n // ============================================================================\n\n /**\n * Render reCAPTCHA v2 checkbox widget.\n *\n * @param containerId - DOM element ID or element to render in\n * @param callback - Callback when user completes challenge\n * @returns Promise resolving to widget ID\n *\n * @throws Error if version is not v2, config missing, or render fails\n *\n * @example\n * ```typescript\n * ngAfterViewInit() {\n * this.recaptcha.render('recaptcha-container', (token) => {\n * this.recaptchaToken = token;\n * this.loginForm.patchValue({ recaptchaToken: token });\n * });\n * }\n * ```\n */\n async render(containerId: string, callback: (token: string) => void): Promise<number> {\n // Skip for platforms that don't support reCAPTCHA\n if (this.shouldSkip()) {\n throw new Error('[RecaptchaService] reCAPTCHA v2 is not supported in SSR or Capacitor native');\n }\n\n // Skip if disabled\n if (!this.config?.enabled) {\n throw new Error('[RecaptchaService] reCAPTCHA is not enabled');\n }\n\n // Only for v2\n if (this.config.version !== 'v2') {\n throw new Error('[RecaptchaService] render() is only for v2. Use execute() for v3/Enterprise.');\n }\n\n // Load script if needed\n await this.loadScript();\n\n // Get grecaptcha object\n const grecaptcha = (window as { grecaptcha?: { render?: (container: string, options: { sitekey: string; callback: (token: string) => void }) => number } }).grecaptcha;\n\n if (!grecaptcha?.render) {\n throw new Error('[RecaptchaService] grecaptcha.render is not available');\n }\n\n // Render widget\n try {\n this.widgetId = grecaptcha.render(containerId, {\n sitekey: this.config.siteKey,\n callback: callback,\n });\n return this.widgetId;\n } catch (error: unknown) {\n throw new Error(`[RecaptchaService] Failed to render reCAPTCHA: ${error instanceof Error ? error.message : 'unknown error'}`);\n }\n }\n\n /**\n * Get response token from v2 widget.\n *\n * @param widgetId - Widget ID (optional, uses last rendered widget if not provided)\n * @returns reCAPTCHA token or null if not completed\n *\n * @example\n * ```typescript\n * const token = this.recaptcha.getResponse();\n * if (token) {\n * await this.auth.login(email, password, token);\n * }\n * ```\n */\n getResponse(widgetId?: number): string | null {\n const grecaptcha = (window as { grecaptcha?: { getResponse?: (widgetId?: number) => string } }).grecaptcha;\n\n if (!grecaptcha?.getResponse) {\n return null;\n }\n\n const id = widgetId !== undefined ? widgetId : this.widgetId ?? undefined;\n return grecaptcha.getResponse(id) || null;\n }\n\n /**\n * Reset v2 widget (clear response).\n *\n * @param widgetId - Widget ID (optional, uses last rendered widget if not provided)\n *\n * @example\n * ```typescript\n * // After failed login\n * this.recaptcha.reset();\n * ```\n */\n reset(widgetId?: number): void {\n const grecaptcha = (window as { grecaptcha?: { reset?: (widgetId?: number) => void } }).grecaptcha;\n\n if (!grecaptcha?.reset) {\n return;\n }\n\n const id = widgetId !== undefined ? widgetId : this.widgetId ?? undefined;\n grecaptcha.reset(id);\n }\n}\n","import { Inject, Injectable, Optional } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport { filter } from 'rxjs/operators';\nimport { NAUTH_CLIENT_CONFIG } from './tokens';\nimport { AngularHttpAdapter } from './http-adapter';\nimport { RecaptchaService } from '../lib/recaptcha.service';\nimport {\n NAuthClient,\n NAuthClientConfig,\n AuthResponseContext,\n ChallengeResponse,\n AuthResponse,\n TokenResponse,\n AuthUser,\n ConfirmForgotPasswordResponse,\n ForgotPasswordResponse,\n ResetPasswordWithCodeResponse,\n UpdateProfileRequest,\n GetChallengeDataResponse,\n GetSetupDataResponse,\n MFAStatus,\n MFADevice,\n AuthEvent,\n SocialProvider,\n SocialLoginOptions,\n LinkedAccountsResponse,\n SocialVerifyRequest,\n AuditHistoryResponse,\n AdminOperations,\n} from '@nauth-toolkit/client';\n\n/**\n * Angular wrapper around NAuthClient that provides promise-based auth methods and reactive state.\n *\n * This service provides:\n * - Reactive state (currentUser$, isAuthenticated$, challenge$)\n * - All core auth methods as Promises (login, signup, logout, refresh)\n * - Profile management (getProfile, updateProfile, changePassword)\n * - Challenge flow methods (respondToChallenge, resendCode)\n * - MFA management (getMfaStatus, setupMfaDevice, etc.)\n * - Social authentication and account linking\n * - Device trust management\n * - Audit history\n *\n * @example\n * ```typescript\n * constructor(private auth: AuthService) {}\n *\n * // Reactive state\n * this.auth.currentUser$.subscribe(user => ...);\n * this.auth.isAuthenticated$.subscribe(isAuth => ...);\n *\n * // Auth operations with async/await\n * const response = await this.auth.login(email, password);\n *\n * // Profile management\n * await this.auth.changePassword(oldPassword, newPassword);\n * const user = await this.auth.updateProfile({ firstName: 'John' });\n *\n * // MFA operations\n * const status = await this.auth.getMfaStatus();\n * ```\n */\n@Injectable()\nexport class AuthService {\n private readonly client: NAuthClient;\n private readonly config: NAuthClientConfig;\n private readonly currentUserSubject = new BehaviorSubject<AuthUser | null>(null);\n private readonly isAuthenticatedSubject = new BehaviorSubject<boolean>(false);\n private readonly challengeSubject = new BehaviorSubject<AuthResponse | null>(null);\n private readonly authEventsSubject = new Subject<AuthEvent>();\n private initialized = false;\n\n /**\n * @param config - Injected client configuration (required)\n * @param httpAdapter - Angular HTTP adapter for making requests (required)\n * @param router - Angular Router (optional, automatically used for navigation if available)\n * @param recaptchaService - RecaptchaService (optional, for automatic token generation)\n */\n constructor(\n @Inject(NAUTH_CLIENT_CONFIG) config: NAuthClientConfig,\n httpAdapter: AngularHttpAdapter,\n @Optional() private router?: Router,\n @Optional() private recaptchaService?: RecaptchaService,\n ) {\n this.config = config;\n\n // Use provided httpAdapter (from config or injected)\n const adapter = config.httpAdapter ?? httpAdapter;\n if (!adapter) {\n throw new Error(\n 'HttpAdapter not found. Either provide httpAdapter in NAUTH_CLIENT_CONFIG or ensure HttpClient is available.',\n );\n }\n\n // ============================================================================\n // Automatic Angular Router integration\n // ============================================================================\n // If Router is available and no custom navigationHandler is provided,\n // automatically use Angular Router's navigateByUrl() to prevent page refreshes\n const navigationHandler =\n config.navigationHandler ??\n (this.router\n ? async (url: string): Promise<void> => {\n await this.router!.navigateByUrl(url);\n }\n : undefined);\n\n // ============================================================================\n // IMPORTANT: Challenge-state hydration BEFORE navigation (Angular guard safety)\n // ============================================================================\n // WHY: `NAuthClient.login()` auto-navigates via ChallengeRouter *before* returning.\n // The Angular sample app uses a synchronous guard (`challengeRouteGuard`) that\n // reads the current challenge via `AuthService.getCurrentChallenge()` (backed by\n // `challengeSubject.value`). If navigation happens before `challengeSubject` is\n // updated, the guard incorrectly redirects back to `/login`.\n //\n // Fix: intercept the SDK's auto-navigation hook (`onAuthResponse`), publish the\n // challenge state immediately, then perform default navigation (or delegate to\n // the user's custom `onAuthResponse` if provided).\n const userOnAuthResponse = config.onAuthResponse;\n\n this.client = new NAuthClient({\n ...config,\n httpAdapter: adapter,\n navigationHandler,\n onAuthResponse: async (response: AuthResponse, context: AuthResponseContext): Promise<void> => {\n // Ensure guards can synchronously see the active challenge before navigation.\n this.updateChallengeState(response);\n\n // If the consumer provided their own handler, let them take full control.\n if (userOnAuthResponse) {\n await userOnAuthResponse(response, context);\n return;\n }\n\n // Default navigation behavior (matches ChallengeRouter.handleAuthResponse)\n const router = this.client.getChallengeRouter();\n if (response.challengeName) {\n await router.navigateToChallenge(response);\n return;\n }\n\n // Prefer appState provided via context (social redirect guard / exchange flow).\n // IMPORTANT: Do not consume/clear persisted OAuth state here; leave it available\n // for consumers via getLastOauthState().\n await router.navigateToSuccess(context.appState ? { appState: context.appState } : undefined, context);\n },\n onAuthStateChange: (user: AuthUser | null) => {\n this.currentUserSubject.next(user);\n this.isAuthenticatedSubject.next(Boolean(user));\n config.onAuthStateChange?.(user);\n },\n });\n\n // Forward all client events to Observable stream\n this.client.on('*', (event: AuthEvent) => {\n this.authEventsSubject.next(event);\n });\n\n // Auto-initialize on construction (hydrate from storage)\n this.initialize();\n }\n\n // ============================================================================\n // Reactive State Observables\n // ============================================================================\n\n /**\n * Current user observable.\n */\n get currentUser$(): Observable<AuthUser | null> {\n return this.currentUserSubject.asObservable();\n }\n\n /**\n * Authenticated state observable.\n */\n get isAuthenticated$(): Observable<boolean> {\n return this.isAuthenticatedSubject.asObservable();\n }\n\n /**\n * Current challenge observable (for reactive challenge navigation).\n */\n get challenge$(): Observable<AuthResponse | null> {\n return this.challengeSubject.asObservable();\n }\n\n /**\n * Authentication events stream.\n * Emits all auth lifecycle events for custom logic, analytics, or UI updates.\n */\n get authEvents$(): Observable<AuthEvent> {\n return this.authEventsSubject.asObservable();\n }\n\n /**\n * Successful authentication events stream.\n * Emits when user successfully authenticates (login, signup, social auth).\n */\n get authSuccess$(): Observable<AuthEvent> {\n return this.authEventsSubject.pipe(filter((e) => e.type === 'auth:success'));\n }\n\n /**\n * Authentication error events stream.\n * Emits when authentication fails (login error, OAuth error, etc.).\n */\n get authError$(): Observable<AuthEvent> {\n return this.authEventsSubject.pipe(filter((e) => e.type === 'auth:error' || e.type === 'oauth:error'));\n }\n\n // ============================================================================\n // Sync State Accessors (for guards, templates)\n // ============================================================================\n\n /**\n * Check if authenticated (sync, uses cached state).\n */\n isAuthenticated(): boolean {\n return this.client.isAuthenticatedSync();\n }\n\n /**\n * Get current user (sync, uses cached state).\n */\n getCurrentUser(): AuthUser | null {\n return this.client.getCurrentUser();\n }\n\n /**\n * Get current challenge (sync).\n */\n getCurrentChallenge(): AuthResponse | null {\n return this.challengeSubject.value;\n }\n\n /**\n * Get challenge router for manual navigation control.\n * Useful for guards that need to handle errors or build custom URLs.\n *\n * @returns ChallengeRouter instance\n *\n * @example\n * ```typescript\n * const router = this.auth.getChallengeRouter();\n * await router.navigateToError('oauth');\n * ```\n */\n getChallengeRouter() {\n return this.client.getChallengeRouter();\n }\n\n // ============================================================================\n // Core Auth Methods\n // ============================================================================\n\n /**\n * Login with identifier and password.\n *\n * Automatically generates reCAPTCHA token if configured (v3 only).\n * For v2 manual mode, pass the token explicitly.\n *\n * @param identifier - User email or username\n * @param password - User password\n * @param recaptchaToken - Optional reCAPTCHA token (for v2 manual mode or when auto-generation is disabled)\n * @returns Promise with auth response or challenge\n *\n * @example Basic Login\n * ```typescript\n * const response = await this.auth.login('user@example.com', 'password');\n * ```\n *\n * @example With Manual reCAPTCHA (v2)\n * ```typescript\n * const response = await this.auth.login('user@example.com', 'password', recaptchaToken);\n * ```\n */\n async login(identifier: string, password: string, recaptchaToken?: string): Promise<AuthResponse> {\n const token = await this.getRecaptchaToken(recaptchaToken, 'login');\n const res = await this.client.login(identifier, password, token);\n return this.updateChallengeState(res);\n }\n\n /**\n * Signup with credentials.\n *\n * Automatically generates reCAPTCHA token if configured (v3 only).\n * For v2 manual mode, include token in payload.\n *\n * @param payload - Signup request payload\n * @returns Promise with auth response or challenge\n *\n * @example Basic Signup\n * ```typescript\n * const response = await this.auth.signup({\n * email: 'new@example.com',\n * password: 'SecurePass123!',\n * firstName: 'John',\n * });\n * ```\n *\n * @example With Manual reCAPTCHA (v2)\n * ```typescript\n * const response = await this.auth.signup({\n * email: 'new@example.com',\n * password: 'SecurePass123!',\n * recaptchaToken: token,\n * });\n * ```\n */\n async signup(payload: Parameters<NAuthClient['signup']>[0]): Promise<AuthResponse> {\n // Auto-generate reCAPTCHA token for v3 if configured and not already provided\n const payloadWithRecaptcha = payload as { recaptchaToken?: string };\n\n if (!payloadWithRecaptcha.recaptchaToken) {\n const token = await this.getRecaptchaToken(undefined, 'signup');\n if (token) {\n payload = { ...payload, recaptchaToken: token };\n }\n }\n\n const res = await this.client.signup(payload);\n return this.updateChallengeState(res);\n }\n\n /**\n * Logout current session.\n *\n * @param forgetDevice - If true, removes device trust\n *\n * @example\n * ```typescript\n * await this.auth.logout();\n * ```\n */\n async logout(forgetDevice?: boolean): Promise<void> {\n await this.client.logout(forgetDevice);\n this.challengeSubject.next(null);\n // Explicitly update auth state after logout\n this.currentUserSubject.next(null);\n this.isAuthenticatedSubject.next(false);\n\n // Clear CSRF token cookie if in cookies mode\n // Note: Backend should clear httpOnly cookies, but we clear non-httpOnly ones\n if (this.config.tokenDelivery === 'cookies' && typeof document !== 'undefined') {\n const csrfCookieName = this.config.csrf?.cookieName ?? 'nauth_csrf_token';\n // Extract domain from baseUrl if possible\n try {\n const url = new URL(this.config.baseUrl);\n document.cookie = `${csrfCookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${url.hostname}`;\n // Also try without domain (for localhost)\n document.cookie = `${csrfCookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n } catch {\n // Fallback if baseUrl parsing fails\n document.cookie = `${csrfCookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n }\n }\n }\n\n /**\n * Logout all sessions.\n *\n * Revokes all active sessions for the current user across all devices.\n * Optionally revokes all trusted devices if forgetDevices is true.\n *\n * @param forgetDevices - If true, also revokes all trusted devices (default: false)\n * @returns Promise with number of sessions revoked\n *\n * @example\n * ```typescript\n * const result = await this.auth.logoutAll();\n * console.log(`Revoked ${result.revokedCount} sessions`);\n * ```\n */\n async logoutAll(forgetDevices?: boolean): Promise<{ revokedCount: number }> {\n const res = await this.client.logoutAll(forgetDevices);\n this.challengeSubject.next(null);\n // Explicitly update auth state after logout\n this.currentUserSubject.next(null);\n this.isAuthenticatedSubject.next(false);\n return res;\n }\n\n /**\n * Refresh tokens.\n *\n * @returns Promise with new tokens\n *\n * @example\n * ```typescript\n * const tokens = await this.auth.refresh();\n * ```\n */\n async refresh(): Promise<TokenResponse> {\n return this.client.refreshTokens();\n }\n\n // ============================================================================\n // Account Recovery (Forgot Password)\n // ============================================================================\n\n /**\n * Request a password reset code (forgot password).\n *\n * @param identifier - User email, username, or phone\n * @returns Promise with password reset response\n *\n * @example\n * ```typescript\n * await this.auth.forgotPassword('user@example.com');\n * ```\n */\n async forgotPassword(identifier: string): Promise<ForgotPasswordResponse> {\n return this.client.forgotPassword(identifier);\n }\n\n /**\n * Confirm a password reset code and set a new password.\n *\n * @param identifier - User email, username, or phone\n * @param code - One-time reset code\n * @param newPassword - New password\n * @returns Promise with confirmation response\n *\n * @example\n * ```typescript\n * await this.auth.confirmForgotPassword('user@example.com', '123456', 'NewPass123!');\n * ```\n */\n async confirmForgotPassword(\n identifier: string,\n code: string,\n newPassword: string,\n ): Promise<ConfirmForgotPasswordResponse> {\n return this.client.confirmForgotPassword(identifier, code, newPassword);\n }\n\n /**\n * Reset password with code or token (generic method for both admin and user-initiated resets).\n *\n * Accepts either:\n * - code: Short numeric code from email/SMS (6-10 digits)\n * - token: Long hex token from reset link (64 chars)\n *\n * @param identifier - User identifier (email, username, phone)\n * @param codeOrToken - Verification code OR token from link\n * @param newPassword - New password\n * @returns Promise with success response\n *\n * @example\n * ```typescript\n * // With code from email\n * await this.auth.resetPasswordWithCode('user@example.com', '123456', 'NewPass123!');\n *\n * // With token from link\n * await this.auth.resetPasswordWithCode('user@example.com', '64-char-token', 'NewPass123!');\n * ```\n */\n async resetPasswordWithCode(\n identifier: string,\n codeOrToken: string,\n newPassword: string,\n ): Promise<ResetPasswordWithCodeResponse> {\n return this.client.resetPasswordWithCode(identifier, codeOrToken, newPassword);\n }\n\n /**\n * Change user password (requires current password).\n *\n * @param oldPassword - Current password\n * @param newPassword - New password (must meet requirements)\n * @returns Promise that resolves when password is changed\n *\n * @example\n * ```typescript\n * await this.auth.changePassword('oldPassword123', 'newSecurePassword456!');\n * ```\n */\n async changePassword(oldPassword: string, newPassword: string): Promise<void> {\n return this.client.changePassword(oldPassword, newPassword);\n }\n\n // ============================================================================\n // Profile Management\n // ============================================================================\n\n /**\n * Get current user profile.\n *\n * @returns Promise of current user profile\n *\n * @example\n * ```typescript\n * const user = await this.auth.getProfile();\n * console.log('User profile:', user);\n * ```\n */\n async getProfile(): Promise<AuthUser> {\n const user = await this.client.getProfile();\n // Update local state when profile is fetched\n this.currentUserSubject.next(user);\n return user;\n }\n\n /**\n * Update user profile.\n *\n * @param updates - Profile fields to update\n * @returns Promise of updated user profile\n *\n * @example\n * ```typescript\n * const user = await this.auth.updateProfile({ firstName: 'John', lastName: 'Doe' });\n * console.log('Profile updated:', user);\n * ```\n */\n async updateProfile(updates: UpdateProfileRequest): Promise<AuthUser> {\n const user = await this.client.updateProfile(updates);\n // Update local state when profile is updated\n this.currentUserSubject.next(user);\n return user;\n }\n\n // ============================================================================\n // Challenge Flow Methods (Essential for any auth flow)\n // ============================================================================\n\n /**\n * Respond to a challenge (VERIFY_EMAIL, VERIFY_PHONE, MFA_REQUIRED, etc.).\n *\n * @param response - Challenge response data\n * @returns Promise with auth response or next challenge\n *\n * @example\n * ```typescript\n * const result = await this.auth.respondToChallenge({\n * session: challengeSession,\n * type: 'VERIFY_EMAIL',\n * code: '123456',\n * });\n * ```\n */\n async respondToChallenge(response: ChallengeResponse): Promise<AuthResponse> {\n const res = await this.client.respondToChallenge(response);\n return this.updateChallengeState(res);\n }\n\n /**\n * Resend challenge code.\n *\n * @param session - Challenge session token\n * @returns Promise with destination information\n *\n * @example\n * ```typescript\n * const result = await this.auth.resendCode(session);\n * console.log('Code sent to:', result.destination);\n * ```\n */\n async resendCode(session: string): Promise<{ destination: string }> {\n return this.client.resendCode(session);\n }\n\n /**\n * Get MFA setup data (for MFA_SETUP_REQUIRED challenge).\n *\n * Returns method-specific setup information:\n * - TOTP: { secret, qrCode, manualEntryKey }\n * - SMS: { maskedPhone }\n * - Email: { maskedEmail }\n * - Passkey: WebAuthn registration options\n *\n * @param session - Challenge session token\n * @param method - MFA method to set up\n * @returns Promise of setup data response\n *\n * @example\n * ```typescript\n * const setupData = await this.auth.getSetupData(session, 'totp');\n * console.log('QR Code:', setupData.setupData.qrCode);\n * ```\n */\n async getSetupData(session: string, method: string): Promise<GetSetupDataResponse> {\n return this.client.getSetupData(session, method as Parameters<NAuthClient['getSetupData']>[1]);\n }\n\n /**\n * Get MFA challenge data (for MFA_REQUIRED challenge - e.g., passkey options).\n *\n * @param session - Challenge session token\n * @param method - Challenge method\n * @returns Promise of challenge data response\n *\n * @example\n * ```typescript\n * const challengeData = await this.auth.getChallengeData(session, 'passkey');\n * ```\n */\n async getChallengeData(session: string, method: string): Promise<GetChallengeDataResponse> {\n return this.client.getChallengeData(session, method as Parameters<NAuthClient['getChallengeData']>[1]);\n }\n\n /**\n * Clear stored challenge (when navigating away from challenge flow).\n *\n * @returns Promise that resolves when challenge is cleared\n *\n * @example\n * ```typescript\n * await this.auth.clearChallenge();\n * ```\n */\n async clearChallenge(): Promise<void> {\n await this.client.clearStoredChallenge();\n this.challengeSubject.next(null);\n }\n\n /**\n * Get current access token (JSON mode only).\n *\n * This is primarily useful for consumers using Angular `HttpClient` directly\n * (outside of the SDK methods) and relying on an interceptor to attach Bearer tokens.\n *\n * @returns Access token, or null if not available\n *\n * @example\n * ```typescript\n * const token = await this.auth.getAccessToken();\n * ```\n */\n async getAccessToken(): Promise<string | null> {\n return await this.client.getAccessToken();\n }\n\n // ============================================================================\n // Social Authentication\n // ============================================================================\n\n /**\n * Initiate social OAuth login flow.\n * Redirects the browser to backend `/auth/social/:provider/redirect`.\n *\n * @param provider - Social provider ('google', 'apple', 'facebook')\n * @param options - Optional redirect options\n * @returns Promise that resolves when redirect starts\n *\n * @example\n * ```typescript\n * await this.auth.loginWithSocial('google', { returnTo: '/auth/callback' });\n * ```\n */\n async loginWithSocial(provider: SocialProvider, options?: SocialLoginOptions): Promise<void> {\n return this.client.loginWithSocial(provider, options);\n }\n\n /**\n * Exchange an exchangeToken (from redirect callback URL) into an AuthResponse.\n *\n * Used for `tokenDelivery: 'json'` or hybrid flows where the backend redirects back\n * with `exchangeToken` instead of setting cookies.\n *\n * @param exchangeToken - One-time exchange token from the callback URL\n * @returns Promise of AuthResponse\n *\n * @example\n * ```typescript\n * const response = await this.auth.exchangeSocialRedirect(exchangeToken);\n * ```\n */\n async exchangeSocialRedirect(exchangeToken: string): Promise<AuthResponse> {\n const res = await this.client.exchangeSocialRedirect(exchangeToken);\n return this.updateChallengeState(res);\n }\n\n /**\n * Verify native social token (mobile).\n *\n * @param request - Social verification request with provider and token\n * @returns Promise of AuthResponse\n *\n * @example\n * ```typescript\n * const result = await this.auth.verifyNativeSocial({\n * provider: 'google',\n * idToken: nativeIdToken,\n * });\n * ```\n */\n async verifyNativeSocial(request: SocialVerifyRequest): Promise<AuthResponse> {\n const res = await this.client.verifyNativeSocial(request);\n return this.updateChallengeState(res);\n }\n\n /**\n * Get linked social accounts.\n *\n * @returns Promise of linked accounts response\n *\n * @example\n * ```typescript\n * const accounts = await this.auth.getLinkedAccounts();\n * console.log('Linked providers:', accounts.providers);\n * ```\n */\n async getLinkedAccounts(): Promise<LinkedAccountsResponse> {\n return this.client.getLinkedAccounts();\n }\n\n /**\n * Link social account.\n *\n * @param provider - Social provider to link\n * @param code - OAuth authorization code\n * @param state - OAuth state parameter\n * @returns Promise with success message\n *\n * @example\n * ```typescript\n * await this.auth.linkSocialAccount('google', code, state);\n * ```\n */\n async linkSocialAccount(provider: string, code: string, state: string): Promise<{ message: string }> {\n return this.client.linkSocialAccount(provider, code, state);\n }\n\n /**\n * Unlink social account.\n *\n * @param provider - Social provider to unlink\n * @returns Promise with success message\n *\n * @example\n * ```typescript\n * await this.auth.unlinkSocialAccount('google');\n * ```\n */\n async unlinkSocialAccount(provider: string): Promise<{ message: string }> {\n return this.client.unlinkSocialAccount(provider);\n }\n\n /**\n * Get the last OAuth appState from social redirect callback.\n *\n * Returns the appState that was stored during the most recent social\n * login redirect callback. This is useful for restoring UI state,\n * applying invite codes, or tracking referral information.\n *\n * The state is automatically cleared after retrieval to prevent reuse.\n *\n * @returns The stored appState, or null if none exists\n *\n * @example\n * ```typescript\n * const appState = await this.auth.getLastOauthState();\n * if (appState) {\n * // Apply invite code or restore UI state\n * console.log('OAuth state:', appState);\n * }\n * ```\n */\n async getLastOauthState(): Promise<string | null> {\n return this.client.getLastOauthState();\n }\n\n // ============================================================================\n // MFA Management\n // ============================================================================\n\n /**\n * Get MFA status for the current user.\n *\n * @returns Promise of MFA status\n *\n * @example\n * ```typescript\n * const status = await this.auth.getMfaStatus();\n * console.log('MFA enabled:', status.enabled);\n * ```\n */\n async getMfaStatus(): Promise<MFAStatus> {\n return this.client.getMfaStatus();\n }\n\n /**\n * Get MFA devices for the current user.\n *\n * @returns Promise of MFA devices array\n *\n * @example\n * ```typescript\n * const devices = await this.auth.getMfaDevices();\n * ```\n */\n async getMfaDevices(): Promise<MFADevice[]> {\n return this.client.getMfaDevices() as Promise<MFADevice[]>;\n }\n\n /**\n * Setup MFA device (authenticated user).\n *\n * @param method - MFA method to set up\n * @returns Promise of setup data\n *\n * @example\n * ```typescript\n * const setupData = await this.auth.setupMfaDevice('totp');\n * ```\n */\n async setupMfaDevice(method: string): Promise<unknown> {\n return this.client.setupMfaDevice(method);\n }\n\n /**\n * Verify MFA setup (authenticated user).\n *\n * @param method - MFA method\n * @param setupData - Setup data from setupMfaDevice\n * @param deviceName - Optional device name\n * @returns Promise with device ID\n *\n * @example\n * ```typescript\n * const result = await this.auth.verifyMfaSetup('totp', { code: '123456' }, 'My Phone');\n * ```\n */\n async verifyMfaSetup(\n method: string,\n setupData: Record<string, unknown>,\n deviceName?: string,\n ): Promise<{ deviceId: number }> {\n return this.client.verifyMfaSetup(method, setupData, deviceName);\n }\n\n /**\n * Remove MFA device.\n *\n * @param method - MFA method to remove\n * @returns Promise with success message\n *\n * @example\n * ```typescript\n * await this.auth.removeMfaDevice('sms');\n * ```\n */\n async removeMfaDevice(method: string): Promise<{ message: string }> {\n return this.client.removeMfaDevice(method);\n }\n\n /**\n * Set preferred MFA method.\n *\n * @param method - Device method to set as preferred ('totp', 'sms', 'email', or 'passkey')\n * @returns Promise with success message\n *\n * @example\n * ```typescript\n * await this.auth.setPreferredMfaMethod('totp');\n * ```\n */\n async setPreferredMfaMethod(method: 'totp' | 'sms' | 'email' | 'passkey'): Promise<{ message: string }> {\n return this.client.setPreferredMfaMethod(method);\n }\n\n /**\n * Generate backup codes.\n *\n * @returns Promise of backup codes array\n *\n * @example\n * ```typescript\n * const codes = await this.auth.generateBackupCodes();\n * console.log('Backup codes:', codes);\n * ```\n */\n async generateBackupCodes(): Promise<string[]> {\n return this.client.generateBackupCodes();\n }\n\n // ============================================================================\n // Device Trust\n // ============================================================================\n\n /**\n * Trust current device.\n *\n * @returns Promise with device token\n *\n * @example\n * ```typescript\n * const result = await this.auth.trustDevice();\n * console.log('Device trusted:', result.deviceToken);\n * ```\n */\n async trustDevice(): Promise<{ deviceToken: string }> {\n return this.client.trustDevice();\n }\n\n /**\n * Check if the current device is trusted.\n *\n * @returns Promise with trusted status\n *\n * @example\n * ```typescript\n * const result = await this.auth.isTrustedDevice();\n * if (result.trusted) {\n * console.log('This device is trusted');\n * }\n * ```\n */\n async isTrustedDevice(): Promise<{ trusted: boolean }> {\n return this.client.isTrustedDevice();\n }\n\n // ============================================================================\n // Audit History\n // ============================================================================\n\n /**\n * Get paginated audit history for the current user.\n *\n * @param params - Query parameters for filtering and pagination\n * @returns Promise of audit history response\n *\n * @example\n * ```typescript\n * const history = await this.auth.getAuditHistory({\n * page: 1,\n * limit: 20,\n * eventTypes: ['LOGIN_SUCCESS'],\n * eventStatus: ['FAILURE'],\n * });\n * console.log('Audit history:', history);\n * ```\n */\n async getAuditHistory(\n params?: Record<string, string | number | boolean | Array<string | number | boolean>>,\n ): Promise<AuditHistoryResponse> {\n return this.client.getAuditHistory(params);\n }\n\n // ============================================================================\n // Escape Hatch\n // ============================================================================\n\n /**\n * Expose underlying NAuthClient for advanced scenarios.\n *\n\n * @returns The underlying NAuthClient instance\n *\n * @example\n * ```typescript\n * // Deprecated - use direct methods instead\n * const status = await this.auth.getClient().getMfaStatus();\n *\n * // Preferred - use direct methods\n * const status = await this.auth.getMfaStatus();\n * ```\n */\n getClient(): NAuthClient {\n return this.client;\n }\n\n // ============================================================================\n // Admin Operations\n // ============================================================================\n\n /**\n * Admin operations (if enabled in config).\n *\n * Provides admin-level user management methods:\n * - User CRUD operations\n * - Password management\n * - Session management\n * - MFA management\n * - Audit history\n *\n * Returns undefined if admin was not configured.\n *\n * @returns AdminOperations instance or undefined\n *\n * @example\n * ```typescript\n * // Check if admin is available\n * if (this.auth.admin) {\n * const users = await this.auth.admin.getUsers({ page: 1 });\n * }\n *\n * // With optional chaining\n * await this.auth.admin?.deleteUser(sub);\n *\n * // Create user\n * const result = await this.auth.admin?.createUser({\n * email: 'user@example.com',\n * password: 'SecurePass123!',\n * isEmailVerified: true,\n * });\n * ```\n */\n get admin(): AdminOperations | undefined {\n return this.client.admin;\n }\n\n // ============================================================================\n // Internal Methods\n // ============================================================================\n\n /**\n * Initialize by hydrating state from storage.\n * Called automatically on construction.\n */\n private async initialize(): Promise<void> {\n if (this.initialized) return;\n this.initialized = true;\n\n await this.client.initialize();\n\n // Hydrate challenge state\n const storedChallenge = await this.client.getStoredChallenge();\n if (storedChallenge) {\n this.challengeSubject.next(storedChallenge);\n }\n\n // Update subjects from client state\n const user = this.client.getCurrentUser();\n if (user) {\n this.currentUserSubject.next(user);\n this.isAuthenticatedSubject.next(true);\n }\n }\n\n /**\n * Update challenge state after auth response.\n */\n private updateChallengeState(response: AuthResponse): AuthResponse {\n if (response.challengeName) {\n this.challengeSubject.next(response);\n } else {\n this.challengeSubject.next(null);\n }\n return response;\n }\n\n // ============================================================================\n // reCAPTCHA Helper\n // ============================================================================\n\n /**\n * Get reCAPTCHA token - auto-generate for v3 or use provided token.\n *\n * Handles platform detection:\n * - Web browser: Generate token if enabled and v3\n * - Capacitor native: Skip (use device attestation instead)\n * - SSR: Skip\n * - Manual mode (v2 or manualChallenge=true): Requires explicit token\n *\n * @param providedToken - Explicitly provided token (v2 manual mode)\n * @param action - Action name for v3 analytics\n * @returns reCAPTCHA token or undefined\n *\n * @private\n */\n private async getRecaptchaToken(providedToken: string | undefined, action: string): Promise<string | undefined> {\n // If token explicitly provided, use it (v2 manual mode)\n if (providedToken) {\n return providedToken;\n }\n\n // No reCAPTCHA service available\n if (!this.recaptchaService) {\n return undefined;\n }\n\n // Check if reCAPTCHA is configured\n const recaptchaConfig = (\n this.config as { recaptcha?: { enabled?: boolean; version?: string; manualChallenge?: boolean } }\n ).recaptcha;\n\n if (!recaptchaConfig?.enabled) {\n return undefined;\n }\n\n // Skip for platforms that don't support reCAPTCHA (SSR, Capacitor native)\n if (this.recaptchaService.shouldSkip()) {\n return undefined;\n }\n\n // v2 or manual mode - user must provide token explicitly\n if (recaptchaConfig.version === 'v2' || recaptchaConfig.manualChallenge) {\n return undefined;\n }\n\n // Auto-generate token for v3/Enterprise\n try {\n return await this.recaptchaService.execute(action);\n } catch (error: unknown) {\n // Log error but don't block authentication\n // Server will enforce if required\n console.warn('[AuthService] Failed to generate reCAPTCHA token:', error);\n return undefined;\n }\n }\n}\n","import { HttpClient, HttpErrorResponse, HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport {\n BehaviorSubject,\n Observable,\n catchError,\n finalize,\n from,\n map,\n of,\n shareReplay,\n switchMap,\n throwError,\n} from 'rxjs';\nimport type { NAuthClientConfig } from '@nauth-toolkit/client';\nimport { AuthService } from '../ngmodule/auth.service';\n\n/**\n * Shared interceptor logic for both:\n * - Functional interceptor (Angular 17+ standalone)\n * - Class-based interceptor (NgModule apps)\n *\n * WHY:\n * - Keep one implementation for cookies + json mode behavior.\n * - Avoid divergence between standalone and NgModule integrations.\n */\n\n// ============================================================================\n// Refresh state management (module-level)\n// ============================================================================\nlet isRefreshing = false;\nconst refreshTokenSubject = new BehaviorSubject<string | null>(null);\nlet refreshInFlight$: Observable<string> | null = null;\nconst retriedRequests = new WeakSet<HttpRequest<unknown>>();\n\n// ============================================================================\n// Error + cookie helpers\n// ============================================================================\n\n/**\n * Safely extract HTTP status code from either:\n * - Angular HttpErrorResponse (HttpClient calls)\n * - SDK NAuthClientError (thrown by the SDK's HttpAdapter)\n */\nfunction getStatusCode(error: unknown): number | null {\n if (error instanceof HttpErrorResponse) return error.status;\n if (typeof error === 'object' && error !== null && 'statusCode' in error) {\n const statusCode = (error as { statusCode?: unknown }).statusCode;\n return typeof statusCode === 'number' ? statusCode : null;\n }\n return null;\n}\n\n/**\n * Best-effort CSRF cookie clearing (non-httpOnly).\n *\n * WARNING: This cannot clear httpOnly auth cookies (access/refresh/device).\n * Those must be cleared by the backend on refresh/logout.\n */\nfunction clearCsrfCookie(baseUrl: string, cookieName: string): void {\n if (typeof document === 'undefined') return;\n\n // WHY: Cookie domain handling differs between localhost and real domains.\n // We try to clear with an explicit domain (if available), then without.\n try {\n const url = new URL(baseUrl);\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${url.hostname}`;\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n } catch {\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n }\n}\n\n/**\n * Get CSRF token from cookie.\n *\n * @param cookieName - Name of the CSRF cookie (from config.csrf.cookieName)\n * @returns CSRF token value or null if not found\n */\nfunction getCsrfToken(cookieName: string): string | null {\n if (typeof document === 'undefined') return null;\n // Escape special regex characters in cookie name to prevent injection\n const escapedCookieName = cookieName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const match = document.cookie.match(new RegExp(`(^| )${escapedCookieName}=([^;]+)`));\n return match ? decodeURIComponent(match[2]) : null;\n}\n\n/**\n * Build retry request with appropriate auth.\n *\n * In cookies mode: Browser automatically sends updated httpOnly cookies (access/refresh tokens).\n * We must re-read CSRF token after refresh to avoid stale headers.\n *\n * In JSON mode: Clones the request and adds the new Bearer token.\n */\nfunction buildRetryRequest(\n originalReq: HttpRequest<unknown>,\n tokenDelivery: string,\n newToken?: string | null,\n csrfConfig?: { cookieName?: string; headerName?: string },\n): HttpRequest<unknown> {\n if (tokenDelivery === 'json' && newToken && newToken !== 'success') {\n return originalReq.clone({ setHeaders: { Authorization: `Bearer ${newToken}` } });\n }\n\n if (tokenDelivery === 'cookies' && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(originalReq.method)) {\n const csrfCookieName = csrfConfig?.cookieName ?? 'nauth_csrf_token';\n const csrfHeaderName = csrfConfig?.headerName ?? 'x-csrf-token';\n // Always refresh CSRF token on retry (even if it exists, get fresh one)\n const freshCsrfToken = getCsrfToken(csrfCookieName);\n if (freshCsrfToken) {\n return originalReq.clone({ setHeaders: { [csrfHeaderName]: freshCsrfToken } });\n }\n }\n\n return originalReq;\n}\n\nexport function createNAuthAuthHttpInterceptor(params: {\n config: NAuthClientConfig;\n http: HttpClient;\n authService: AuthService;\n router: Router;\n next: HttpHandlerFn;\n req: HttpRequest<unknown>;\n}): Observable<HttpEvent<unknown>> {\n const { config, authService, router, next, req } = params;\n\n const tokenDelivery = config.tokenDelivery;\n const baseUrl = config.baseUrl;\n const endpoints = config.endpoints ?? {};\n const authPathPrefix = config.authPathPrefix;\n\n // Build refresh path with authPathPrefix if configured (matches core client buildUrl logic exactly)\n // Use default '/refresh' if endpoints.refresh is not defined\n const refreshPath = endpoints?.refresh ?? '/refresh';\n const normalizedRefreshPath = refreshPath.startsWith('/') ? refreshPath : `/${refreshPath}`;\n\n // Check if baseUrl already ends with authPathPrefix to avoid double-prefixing\n // This must match the core client's buildUrl logic exactly\n const baseUrlEndsWithPrefix = authPathPrefix && baseUrl.endsWith(authPathPrefix);\n\n const shouldAddPrefix = authPathPrefix && !baseUrlEndsWithPrefix && !normalizedRefreshPath.startsWith(authPathPrefix);\n const effectiveRefreshPath = shouldAddPrefix ? `${authPathPrefix}${normalizedRefreshPath}` : normalizedRefreshPath;\n\n const loginPath = endpoints.login ?? '/login';\n const signupPath = endpoints.signup ?? '/signup';\n const socialExchangePath = endpoints.socialExchange ?? '/social/exchange';\n\n const isAuthApiRequest = req.url.includes(baseUrl);\n // Check if request is to refresh endpoint (using effective path with authPathPrefix)\n const isRefreshEndpoint = req.url.includes(effectiveRefreshPath);\n const isPublicEndpoint =\n req.url.includes(loginPath) || req.url.includes(signupPath) || req.url.includes(socialExchangePath);\n const shouldIntercept = isAuthApiRequest && !isRefreshEndpoint && !isPublicEndpoint;\n\n // ============================================================================\n // Build request for cookies mode (withCredentials + CSRF)\n // ============================================================================\n // IMPORTANT: When using AngularHttpAdapter, headers from buildHeaders() are passed\n // to HttpClient.request() as a plain object. Angular converts these to HttpHeaders\n // and creates an HttpRequest. However, we cannot rely on buildHeaders() to add CSRF\n // in Angular context because:\n // 1. hasWindow() might return false in SSR contexts\n // 2. Headers might not be properly merged into the HttpRequest that interceptors receive\n // 3. The interceptor is the authoritative place for CSRF in Angular apps\n //\n // Therefore, the interceptor ALWAYS adds CSRF for mutating methods in cookies mode,\n // regardless of whether buildHeaders() added it (for vanilla clients).\n let authReq = req;\n if (tokenDelivery === 'cookies') {\n authReq = authReq.clone({ withCredentials: true });\n // Add CSRF token for mutating methods (POST, PUT, PATCH, DELETE)\n // Always add it here - don't rely on buildHeaders() in Angular context\n // Add CSRF token for mutating methods (POST, PUT, PATCH, DELETE)\n // This runs for ALL requests in cookies mode, not just auth API requests\n // This ensures CSRF protection for all mutating operations\n if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)) {\n // Respect user's CSRF config, fallback to defaults if not provided\n // These defaults must match the backend's CSRF configuration\n const csrfCookieName = config.csrf?.cookieName ?? 'nauth_csrf_token';\n const csrfHeaderName = config.csrf?.headerName ?? 'x-csrf-token';\n\n // Get CSRF token from cookie using the configured cookie name\n const csrfToken = getCsrfToken(csrfCookieName);\n\n if (csrfToken) {\n // Use setHeaders which will override if already exists (from buildHeaders)\n // This ensures CSRF is always present for DELETE and other mutating methods\n authReq = authReq.clone({ setHeaders: { [csrfHeaderName]: csrfToken } });\n } else {\n // CSRF token not found - this could happen if:\n // 1. Cookie doesn't exist (before first login, after logout, or cookie expired)\n // 2. Cookie name mismatch (check config.csrf.cookieName matches backend)\n // 3. Cookie is httpOnly and can't be read (but CSRF cookies should be readable)\n // The backend should handle missing CSRF tokens appropriately (return 403 or similar)\n }\n }\n }\n\n // ============================================================================\n // JSON mode: attach Authorization header for HttpClient calls\n // ============================================================================\n // Simple approach: attach token if available, let backend validate\n // Handle 401 reactively (matches old working implementation)\n const attachJsonAuth$ =\n tokenDelivery === 'json' && shouldIntercept && !authReq.headers.has('Authorization')\n ? from(authService.getAccessToken()).pipe(\n switchMap((token) => {\n if (token) {\n return of(authReq.clone({ setHeaders: { Authorization: `Bearer ${token}` } }));\n }\n return of(authReq);\n }),\n )\n : of(authReq);\n\n // ============================================================================\n // Refresh coordination\n // ============================================================================\n const getOrStartRefresh$ = (): Observable<string> => {\n if (refreshInFlight$) return refreshInFlight$;\n\n // WHY: We want to ensure only one refresh request is in flight at any time.\n // All requests (including those that haven't hit the backend yet) should wait for\n // the same refresh result to avoid a burst of 401s and potential WAF/rate-limit issues.\n isRefreshing = true;\n refreshTokenSubject.next(null);\n\n // WHY: Always refresh via the core client.\n // - Ensures authPathPrefix + default endpoints are applied consistently (fixes /refresh vs /auth/refresh).\n // - Centralizes CSRF + credentials handling in one place.\n const refreshRequest$ = from(authService.getClient().refreshTokens());\n\n refreshInFlight$ = refreshRequest$.pipe(\n map((response) => {\n // Cookies mode: success is enough (tokens are in httpOnly cookies).\n // JSON mode: we need the new access token to retry + unblock queued requests.\n const newToken = tokenDelivery === 'json' ? response.accessToken : 'success';\n\n if (tokenDelivery === 'json' && (!newToken || newToken === 'success')) {\n // ⚠️ WARNING: Without an access token we cannot safely retry requests in JSON mode.\n throw new Error('Token refresh did not return an access token');\n }\n\n refreshTokenSubject.next(newToken ?? 'success');\n return newToken ?? 'success';\n }),\n catchError((err) => {\n refreshTokenSubject.next(null);\n\n const statusCode = getStatusCode(err);\n\n // Refresh failed with 401 => session expired.\n // Clear *local* SDK state so guards/pages don't think the user is still logged in after navigation/reload.\n if (statusCode === 401) {\n // Best-effort: also clear CSRF cookie in cookies mode (non-httpOnly).\n if (tokenDelivery === 'cookies') {\n const csrfCookieName = config.csrf?.cookieName ?? 'nauth_csrf_token';\n clearCsrfCookie(config.baseUrl, csrfCookieName);\n }\n\n return from(authService.getClient().clearLocalAuthState()).pipe(\n switchMap(() => {\n // Call onSessionExpired callback if configured\n config.onSessionExpired?.();\n\n if (config.redirects?.sessionExpired) {\n router.navigateByUrl(config.redirects.sessionExpired).catch(() => {\n // Ignore navigation errors\n });\n }\n return throwError(() => err);\n }),\n );\n }\n\n return throwError(() => err);\n }),\n finalize(() => {\n isRefreshing = false;\n refreshInFlight$ = null;\n }),\n shareReplay({ bufferSize: 1, refCount: false }),\n );\n\n return refreshInFlight$;\n };\n\n // ============================================================================\n // Pre-request gating: block requests while refresh is in-flight\n // ============================================================================\n // WHY: Prevent multiple requests from hitting the backend with an expired token and returning 401.\n // We queue all auth API calls during refresh and release them once refresh succeeds.\n if (shouldIntercept && isRefreshing && refreshInFlight$) {\n return refreshInFlight$.pipe(\n switchMap((token) => {\n const gatedReq = buildRetryRequest(authReq, tokenDelivery, token, config.csrf);\n return next(gatedReq);\n }),\n );\n }\n\n return attachJsonAuth$.pipe(\n switchMap((requestWithAuth) =>\n next(requestWithAuth).pipe(\n catchError((error: unknown) => {\n const shouldHandle =\n error instanceof HttpErrorResponse && error.status === 401 && shouldIntercept && !retriedRequests.has(req);\n\n if (!shouldHandle) {\n return throwError(() => error);\n }\n\n retriedRequests.add(req);\n\n return getOrStartRefresh$().pipe(\n switchMap((token) => {\n const retryReq = buildRetryRequest(requestWithAuth, tokenDelivery, token, config.csrf);\n retriedRequests.add(retryReq);\n return next(retryReq);\n }),\n );\n }),\n ),\n ),\n );\n}\n","import { Injectable, Inject } from '@angular/core';\nimport { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpClient } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { Observable } from 'rxjs';\nimport { NAUTH_CLIENT_CONFIG } from './tokens';\nimport { AuthService } from './auth.service';\nimport { NAuthClientConfig } from '@nauth-toolkit/client';\nimport { createNAuthAuthHttpInterceptor } from '../lib/auth-interceptor.shared';\n\n/**\n * Class-based HTTP interceptor for NgModule apps (Angular < 17).\n *\n * For standalone components (Angular 17+), use the functional `authInterceptor` instead.\n *\n * @example\n * ```typescript\n * // app.module.ts\n * import { HTTP_INTERCEPTORS } from '@angular/common/http';\n * import { AuthInterceptorClass } from '@nauth-toolkit/client-angular';\n *\n * @NgModule({\n * providers: [\n * { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptorClass, multi: true }\n * ]\n * })\n * ```\n */\n@Injectable()\nexport class AuthInterceptorClass implements HttpInterceptor {\n constructor(\n @Inject(NAUTH_CLIENT_CONFIG) private readonly config: NAuthClientConfig,\n private readonly http: HttpClient,\n private readonly authService: AuthService,\n private readonly router: Router,\n ) {}\n\n intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\n return createNAuthAuthHttpInterceptor({\n config: this.config,\n http: this.http,\n authService: this.authService,\n router: this.router,\n req,\n next: (r) => next.handle(r),\n });\n }\n}\n","import { inject, Inject, Injectable, Optional } from '@angular/core';\nimport { CanActivateFn, Router, UrlTree } from '@angular/router';\nimport { AuthService } from '../ngmodule/auth.service';\nimport { NAUTH_CLIENT_CONFIG } from '../ngmodule/tokens';\nimport type { NAuthClientConfig } from '@nauth-toolkit/client';\n\n/**\n * Functional route guard for authentication (Angular 17+).\n *\n * Protects routes by checking if user is authenticated.\n * Redirects to configured session expired route (or login) if not authenticated.\n *\n * @param redirectTo - Optional path to redirect to if not authenticated. If not provided, uses `redirects.sessionExpired` from config (defaults to '/login')\n * @returns CanActivateFn guard function\n *\n * @example\n * ```typescript\n * // In route configuration - uses config.redirects.sessionExpired\n * const routes: Routes = [\n * {\n * path: 'home',\n * component: HomeComponent,\n * canActivate: [authGuard()]\n * }\n * ];\n *\n * // Override with custom route\n * const routes: Routes = [\n * {\n * path: 'admin',\n * component: AdminComponent,\n * canActivate: [authGuard('/admin/login')]\n * }\n * ];\n * ```\n */\nexport function authGuard(redirectTo?: string): CanActivateFn {\n return (): boolean | UrlTree => {\n const auth = inject(AuthService);\n const router = inject(Router);\n const config = inject(NAUTH_CLIENT_CONFIG, { optional: true });\n\n if (auth.isAuthenticated()) {\n return true;\n }\n\n // Use provided redirectTo, or config.redirects.sessionExpired, or default to '/login'\n const redirectPath = redirectTo ?? config?.redirects?.sessionExpired ?? '/login';\n\n return router.createUrlTree([redirectPath]);\n };\n}\n\n/**\n * Class-based authentication guard for NgModule compatibility.\n *\n * **Note:** When using `NAuthModule.forRoot()`, `AuthGuard` is automatically provided\n * and has access to the configuration. You don't need to add it to your module's providers.\n *\n * @example\n * ```typescript\n * // app.module.ts - AuthGuard is automatically provided by NAuthModule.forRoot()\n * @NgModule({\n * imports: [\n * NAuthModule.forRoot({\n * baseUrl: 'https://api.example.com/auth',\n * tokenDelivery: 'cookies',\n * redirects: {\n * sessionExpired: '/login?expired=true',\n * },\n * }),\n * RouterModule.forRoot([\n * {\n * path: 'home',\n * component: HomeComponent,\n * canActivate: [AuthGuard], // Uses config.redirects.sessionExpired\n * },\n * ]),\n * ],\n * })\n * export class AppModule {}\n *\n * // Or provide manually in a feature module (still has access to root config)\n * @NgModule({\n * providers: [AuthGuard],\n * })\n * export class FeatureModule {}\n * ```\n */\n@Injectable()\nexport class AuthGuard {\n /**\n * @param auth - Authentication service\n * @param router - Angular router\n * @param config - Optional client configuration (injected automatically)\n */\n constructor(\n private auth: AuthService,\n private router: Router,\n @Optional() @Inject(NAUTH_CLIENT_CONFIG) private config?: NAuthClientConfig,\n ) {}\n\n /**\n * Check if route can be activated.\n *\n * @returns True if authenticated, otherwise redirects to configured session expired route (or '/login')\n */\n canActivate(): boolean | UrlTree {\n if (this.auth.isAuthenticated()) {\n return true;\n }\n\n // Use config.redirects.sessionExpired or default to '/login'\n const redirectPath = this.config?.redirects?.sessionExpired ?? '/login';\n\n return this.router.createUrlTree([redirectPath]);\n }\n}\n","import { NgModule, ModuleWithProviders, inject, Optional, APP_INITIALIZER } from '@angular/core';\nimport { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { NAUTH_CLIENT_CONFIG, NAuthAngularConfig } from './tokens';\nimport { AuthService } from './auth.service';\nimport { AngularHttpAdapter } from './http-adapter';\nimport { AuthInterceptorClass } from './auth.interceptor.class';\nimport { AuthGuard } from '../lib/auth.guard';\nimport { RecaptchaService, RECAPTCHA_CONFIG } from '../lib/recaptcha.service';\n\n/**\n * NgModule for nauth-toolkit Angular integration.\n *\n * Use this for NgModule-based apps (Angular 17+ with NgModule or legacy apps).\n *\n * @example Basic Setup\n * ```typescript\n * // app.module.ts\n * import { NAuthModule } from '@nauth-toolkit/client-angular';\n *\n * @NgModule({\n * imports: [\n * NAuthModule.forRoot({\n * baseUrl: 'http://localhost:3000/auth',\n * tokenDelivery: 'cookies',\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n *\n * @example With reCAPTCHA Enterprise\n * ```typescript\n * NAuthModule.forRoot({\n * baseUrl: 'http://localhost:3000/auth',\n * tokenDelivery: 'cookies',\n * recaptcha: {\n * enabled: true,\n * version: 'enterprise',\n * siteKey: environment.recaptchaSiteKey,\n * action: 'login',\n * },\n * })\n * ```\n */\n@NgModule({\n imports: [HttpClientModule],\n exports: [HttpClientModule],\n})\nexport class NAuthModule {\n static forRoot(config: NAuthAngularConfig): ModuleWithProviders<NAuthModule> {\n const providers: any[] = [\n {\n provide: NAUTH_CLIENT_CONFIG,\n useValue: config,\n },\n AngularHttpAdapter,\n {\n provide: AuthService,\n useFactory: (httpAdapter: AngularHttpAdapter, recaptchaService?: RecaptchaService) => {\n // Try to inject Router optionally - if not available, pass undefined\n // Router will be undefined if not provided (e.g., in apps without routing)\n const router = inject(Router, { optional: true });\n return new AuthService(config, httpAdapter, router ?? undefined, recaptchaService);\n },\n deps: [AngularHttpAdapter, [new Optional(), RecaptchaService]],\n },\n {\n provide: HTTP_INTERCEPTORS,\n useClass: AuthInterceptorClass,\n multi: true,\n },\n // Provide AuthGuard so it has access to NAUTH_CLIENT_CONFIG\n AuthGuard,\n ];\n\n // Add reCAPTCHA providers if configured\n if (config.recaptcha?.enabled) {\n providers.push(\n {\n provide: RECAPTCHA_CONFIG,\n // Cast because interface extends but they're compatible\n useValue: config.recaptcha,\n },\n RecaptchaService,\n {\n provide: APP_INITIALIZER,\n useFactory: () => {\n // Force RecaptchaService instantiation at app startup so script preloads\n inject(RecaptchaService);\n // No-op - constructor already handles preload\n return () => {};\n },\n multi: true,\n },\n );\n }\n\n return {\n ngModule: NAuthModule,\n providers,\n };\n }\n}\n","import { inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { HttpHandlerFn, HttpInterceptorFn, HttpRequest, HttpClient } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { NAUTH_CLIENT_CONFIG } from '../ngmodule/tokens';\nimport { AuthService } from '../ngmodule/auth.service';\nimport { createNAuthAuthHttpInterceptor } from './auth-interceptor.shared';\n\n/**\n * Angular HTTP interceptor for nauth-toolkit.\n *\n * Handles:\n * - Cookies mode: withCredentials + CSRF tokens + refresh via POST\n * - JSON mode: refresh via SDK, retry with new token\n */\nexport const authInterceptor: HttpInterceptorFn = (req: HttpRequest<unknown>, next: HttpHandlerFn) => {\n const config = inject(NAUTH_CLIENT_CONFIG);\n const http = inject(HttpClient);\n const authService = inject(AuthService);\n const platformId = inject(PLATFORM_ID);\n const router = inject(Router);\n const isBrowser = isPlatformBrowser(platformId);\n\n if (!isBrowser) {\n return next(req);\n }\n\n return createNAuthAuthHttpInterceptor({ config, http, authService, router, next, req });\n};\n\n/**\n * Class-based interceptor for NgModule compatibility.\n */\nexport class AuthInterceptor {\n intercept(req: HttpRequest<unknown>, next: HttpHandlerFn) {\n return authInterceptor(req, next);\n }\n}\n","import { inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { type CanActivateFn } from '@angular/router';\nimport { AuthService } from '../ngmodule/auth.service';\nimport { NAuthClientError, NAuthErrorCode, type AuthResponse } from '@nauth-toolkit/client';\n\n/**\n * Social redirect callback route guard.\n *\n * This guard supports the redirect-first social flow where the backend redirects\n * back to the frontend with:\n * - `appState` (always optional)\n * - `exchangeToken` (present for json/hybrid flows, and for cookie flows that return a challenge)\n * - `error` / `error_description` (provider errors)\n *\n * Behavior:\n * - If `exchangeToken` exists: exchanges it via backend (SDK handles navigation automatically).\n * - If no `exchangeToken`: treat as cookie-success path (SDK handles navigation automatically).\n * - If `error` exists: redirects to oauthError route.\n * - If auto-redirect is disabled (redirectUrls set to null): returns true to activate the route.\n *\n * @example\n * ```typescript\n * import { socialRedirectCallbackGuard } from '@nauth-toolkit/client/angular';\n *\n * export const routes: Routes = [\n * { path: 'auth/callback', canActivate: [socialRedirectCallbackGuard], component: CallbackComponent },\n * ];\n * ```\n */\nexport const socialRedirectCallbackGuard: CanActivateFn = async (): Promise<boolean> => {\n const auth = inject(AuthService);\n const platformId = inject(PLATFORM_ID);\n const isBrowser = isPlatformBrowser(platformId);\n\n if (!isBrowser) {\n return false;\n }\n\n const params = new URLSearchParams(window.location.search);\n const error = params.get('error');\n const exchangeToken = params.get('exchangeToken');\n const appState = params.get('appState');\n\n const router = auth.getChallengeRouter();\n\n // ============================================================================\n // Extract and store appState if present\n // ============================================================================\n // WHY: appState is round-tripped from the OAuth flow and should be stored\n // for retrieval via getLastOauthState() and passed to the success route.\n if (appState) {\n await auth.getClient().storeOauthState(appState);\n }\n\n // Provider error: redirect to oauthError (or activate route if auto-redirect disabled)\n if (error) {\n await router.navigateToError('oauth');\n // Return true to activate route if oauthError redirect is disabled\n return router.isErrorRedirectDisabled('oauth');\n }\n\n // No exchangeToken: cookie success path; hydrate then navigate to success.\n //\n // Note: When auto-redirect is enabled, we do not \"activate\" the callback route to avoid\n // consumers needing to render a page. When disabled, we activate the route.\n if (!exchangeToken) {\n // ============================================================================\n // Cookies mode: hydrate user state before redirecting\n // ============================================================================\n // WHY: In cookie delivery, the OAuth callback completes via browser redirects, so the frontend\n // does not receive a JSON AuthResponse to populate the SDK's cached `currentUser`.\n //\n // Without this, sync guards (`authGuard`) can immediately redirect to /login because\n // `currentUser` is still null even though cookies were set successfully.\n try {\n const user = await auth.getProfile();\n\n // ============================================================================\n // Route through handleAuthResponse to ensure onAuthResponse is called\n // ============================================================================\n // WHY: onAuthResponse should be called consistently for all auth completions,\n // whether via exchange token or cookie success path. This allows apps to have\n // a single handler for all authentication outcomes (login, signup, social).\n //\n // We construct a synthetic AuthResponse with the user data. Tokens are omitted\n // because they're in httpOnly cookies, not accessible to the client.\n const syntheticResponse: AuthResponse = {\n user: {\n sub: user.sub,\n email: user.email,\n firstName: user.firstName,\n lastName: user.lastName,\n phone: user.phone,\n isEmailVerified: user.isEmailVerified,\n isPhoneVerified: user.isPhoneVerified,\n socialProviders: user.socialProviders,\n hasPasswordHash: user.hasPasswordHash,\n },\n authMethod: user.sessionAuthMethod ?? undefined,\n };\n\n // Call handleAuthResponse which respects onAuthResponse callback\n // Pass appState in context so onAuthResponse can access it\n await router.handleAuthResponse(syntheticResponse, {\n source: 'social',\n appState: appState ?? undefined,\n });\n } catch (error: unknown) {\n // Only treat auth failures (401/403) as OAuth errors\n // Network errors or other issues might be temporary - still try success route\n\n // Type guard: check if error is NAuthClientError\n if (error instanceof NAuthClientError) {\n const isAuthError =\n error.statusCode === 401 ||\n error.statusCode === 403 ||\n error.code === NAuthErrorCode.AUTH_TOKEN_INVALID ||\n error.code === NAuthErrorCode.AUTH_SESSION_EXPIRED ||\n error.code === NAuthErrorCode.AUTH_SESSION_NOT_FOUND;\n\n if (isAuthError) {\n // Cookies weren't set properly - OAuth failed\n await router.navigateToError('oauth');\n return router.isErrorRedirectDisabled('oauth');\n }\n }\n\n // For network errors or other non-auth issues, proceed to success route\n // The auth guard will handle authentication state on the next route\n await router.navigateToSuccess(appState ? { appState } : undefined);\n }\n\n // Return true if success redirect is disabled, allowing the callback component to render\n return router.isSuccessRedirectDisabled({ source: 'social', appState: appState ?? undefined });\n }\n\n // Exchange token - SDK handles navigation automatically\n // Note: appState will be passed via query params when navigateToSuccess is called\n // by the challenge router after successful exchange\n await auth.exchangeSocialRedirect(exchangeToken);\n\n // Return true if success redirect is disabled, allowing the callback component to render\n // We use 'social' as source since this is the social OAuth callback flow\n return router.isSuccessRedirectDisabled({ source: 'social', appState: appState ?? undefined });\n};\n","import { inject, EnvironmentProviders, makeEnvironmentProviders, APP_INITIALIZER } from '@angular/core';\nimport { RecaptchaService, RECAPTCHA_CONFIG, RecaptchaServiceConfig } from './recaptcha.service';\nimport { NAUTH_CLIENT_CONFIG } from '../ngmodule/tokens';\n\n/**\n * Provides reCAPTCHA configuration and automatic script preloading.\n *\n * **IMPORTANT:** When using with `NAUTH_CLIENT_CONFIG`, you must pass\n * `provideRecaptcha()` call MUST appear AFTER the `NAUTH_CLIENT_CONFIG` provider.\n *\n * Sets up `RECAPTCHA_CONFIG` and `RecaptchaService`. When called without config,\n * reads from `NAUTH_CLIENT_CONFIG.recaptcha` if available.\n *\n * @param config - Optional. reCAPTCHA config (enabled, version, siteKey, action).\n * If omitted, will attempt to use `NAUTH_CLIENT_CONFIG.recaptcha`.\n * Pass explicitly when not using NAuth or to override.\n * @returns Environment providers for reCAPTCHA\n *\n * @example With NAUTH_CLIENT_CONFIG (no duplication)\n * ```typescript\n * providers: [\n * { provide: NAUTH_CLIENT_CONFIG, useValue: { baseUrl: '...', recaptcha: { enabled: true, version: 'enterprise', siteKey: '...', action: 'login' } } },\n * provideRecaptcha(), // reads NAUTH_CLIENT_CONFIG.recaptcha at runtime\n * ]\n * ```\n *\n * @example Without NAuth (explicit config)\n * ```typescript\n * provideRecaptcha({ enabled: true, version: 'v3', siteKey: '...', action: 'login' })\n * ```\n */\nexport function provideRecaptcha(config?: RecaptchaServiceConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: RECAPTCHA_CONFIG,\n useFactory: (): RecaptchaServiceConfig | undefined => {\n if (config !== undefined) {\n return config;\n }\n // Try to inject NAUTH_CLIENT_CONFIG at runtime\n try {\n const clientConfig = inject(NAUTH_CLIENT_CONFIG, { optional: true });\n const recaptchaConfig = clientConfig?.recaptcha;\n\n // Debug log when debug is enabled\n if (typeof console !== 'undefined' && clientConfig?.debug && recaptchaConfig) {\n console.log('[provideRecaptcha] Using NAUTH_CLIENT_CONFIG.recaptcha');\n }\n\n return recaptchaConfig as RecaptchaServiceConfig | undefined;\n } catch {\n // Injection failed (NAUTH_CLIENT_CONFIG not available)\n return undefined;\n }\n },\n },\n RecaptchaService,\n {\n provide: APP_INITIALIZER,\n useFactory: () => {\n return () => {\n const c = inject(RECAPTCHA_CONFIG);\n if (c?.enabled && (c.version === 'v3' || c.version === 'enterprise')) {\n inject(RecaptchaService)\n .loadScript()\n .catch(() => {});\n }\n };\n },\n multi: true,\n },\n ]);\n}\n","/**\n * Public API Surface of @nauth-toolkit/client-angular (NgModule)\n *\n * This is the default entry point for NgModule-based Angular apps.\n * For standalone components, use: @nauth-toolkit/client-angular/standalone\n */\n\n// Re-export core client types and utilities\nexport * from '@nauth-toolkit/client';\n\n// Export NgModule-specific components (class-based)\nexport * from './ngmodule/tokens';\nexport * from './ngmodule/auth.service';\nexport * from './ngmodule/http-adapter';\nexport * from './ngmodule/auth.interceptor.class';\nexport * from './ngmodule/nauth.module';\n\n// Export functional components (for flexibility in NgModule apps too)\nexport * from './lib/auth.interceptor';\nexport * from './lib/auth.guard';\nexport * from './lib/social-redirect-callback.guard';\nexport * from './lib/recaptcha.service';\nexport * from './lib/recaptcha-provider';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.AngularHttpAdapter","i3.RecaptchaService","i2.AuthService","i3"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nauth-toolkit-client-angular.mjs","sources":["../../src/ngmodule/tokens.ts","../../src/ngmodule/http-adapter.ts","../../src/lib/recaptcha.service.ts","../../src/ngmodule/auth.service.ts","../../src/lib/auth-interceptor.shared.ts","../../src/ngmodule/auth.interceptor.class.ts","../../src/lib/auth.guard.ts","../../src/ngmodule/nauth.module.ts","../../src/lib/auth.interceptor.ts","../../src/lib/social-redirect-callback.guard.ts","../../src/lib/recaptcha-provider.ts","../../src/public-api.ts","../../src/nauth-toolkit-client-angular.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { NAuthClientConfig } from '@nauth-toolkit/client';\n\n/**\n * reCAPTCHA configuration for Angular client.\n *\n * Extends base client RecaptchaConfig with Angular-specific options.\n *\n * @example v3 Automatic Mode\n * ```typescript\n * {\n * enabled: true,\n * version: 'v3',\n * siteKey: '6LcExample_Site_Key',\n * action: 'login',\n * autoLoadScript: true,\n * }\n * ```\n *\n * @example v2 Manual Mode\n * ```typescript\n * {\n * enabled: true,\n * version: 'v2',\n * siteKey: '6LcExample_Site_Key',\n * manualChallenge: true,\n * }\n * ```\n */\nexport interface RecaptchaAngularConfig {\n /**\n * Enable/disable reCAPTCHA.\n * Set to false to disable even if configured (useful for testing).\n */\n enabled: boolean;\n\n /**\n * reCAPTCHA version: v2 (checkbox), v3 (invisible), or enterprise.\n */\n version: 'v2' | 'v3' | 'enterprise';\n\n /**\n * Site key from Google reCAPTCHA console.\n * This is safe to expose publicly (it's the public key).\n */\n siteKey: string;\n\n /**\n * Action name for v3/Enterprise analytics.\n * Helps track which actions are being protected.\n * Common values: 'login', 'signup', 'submit'\n *\n * @default 'submit'\n */\n action?: string;\n\n /**\n * Manual challenge mode (v2 only).\n * If true, you must manually call RecaptchaService.render() and get token.\n * If false, AuthService auto-generates token before login/signup.\n *\n * @default false\n */\n manualChallenge?: boolean;\n\n /**\n * Automatically load the Google reCAPTCHA script.\n * If false, you must manually load the script.\n *\n * @default true\n */\n autoLoadScript?: boolean;\n\n /**\n * Language code for reCAPTCHA widget (v2 only).\n * @example 'en', 'es', 'fr', 'de'\n * @default Browser language\n */\n language?: string;\n}\n\n/**\n * Angular-specific NAuth configuration.\n *\n * Extends base NAuthClientConfig with Angular-specific options.\n *\n * @example\n * ```typescript\n * const config: NAuthAngularConfig = {\n * baseUrl: 'https://api.example.com/auth',\n * tokenDelivery: 'cookies',\n * recaptcha: {\n * enabled: true,\n * version: 'v3',\n * siteKey: '6LcExample_Site_Key',\n * action: 'login',\n * },\n * };\n * ```\n */\nexport interface NAuthAngularConfig extends NAuthClientConfig {\n /**\n * Google reCAPTCHA configuration (optional).\n * Provides bot protection for login/signup endpoints.\n */\n recaptcha?: RecaptchaAngularConfig;\n}\n\n/**\n * Injection token for providing NAuthClientConfig in Angular apps.\n */\nexport const NAUTH_CLIENT_CONFIG = new InjectionToken<NAuthClientConfig>('NAUTH_CLIENT_CONFIG');\n","import { Injectable } from '@angular/core';\nimport { HttpClient, HttpErrorResponse } from '@angular/common/http';\nimport { firstValueFrom } from 'rxjs';\nimport { HttpAdapter, HttpRequest, HttpResponse, NAuthClientError, NAuthErrorCode } from '@nauth-toolkit/client';\n\n/**\n * HTTP adapter for Angular using HttpClient.\n *\n * This adapter:\n * - Uses Angular's HttpClient for all requests\n * - Works with Angular's HTTP interceptors (including authInterceptor)\n * - Auto-provided via Angular DI (providedIn: 'root')\n * - Converts HttpClient responses to HttpResponse format\n * - Converts HttpErrorResponse to NAuthClientError\n *\n * Users don't need to configure this manually - it's automatically\n * injected when using AuthService in Angular apps.\n *\n * @example\n * ```typescript\n * // Automatic usage (no manual setup needed)\n * // AuthService automatically injects AngularHttpAdapter\n * constructor(private auth: AuthService) {}\n * ```\n */\n@Injectable()\nexport class AngularHttpAdapter implements HttpAdapter {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Safely parse a JSON response body.\n *\n * Angular's fetch backend (`withFetch()`) will throw a raw `SyntaxError` if\n * `responseType: 'json'` is used and the backend returns HTML (common for\n * proxies, 502 pages, SSR fallbacks, or misrouted requests).\n *\n * To avoid crashing consumer apps, we always request as text and then parse\n * JSON only when the response actually looks like JSON.\n *\n * @param bodyText - Raw response body as text\n * @param contentType - Content-Type header value (if available)\n * @returns Parsed JSON value (unknown)\n * @throws {SyntaxError} When body is non-empty but not valid JSON\n */\n private parseJsonBody(bodyText: string, contentType: string | null): unknown {\n const trimmed = bodyText.trim();\n if (!trimmed) return null;\n\n // If it's clearly HTML, never attempt JSON.parse (some proxies mislabel Content-Type).\n if (trimmed.startsWith('<')) {\n return bodyText;\n }\n\n const looksLikeJson = trimmed.startsWith('{') || trimmed.startsWith('[');\n const isJsonContentType = typeof contentType === 'string' && contentType.toLowerCase().includes('application/json');\n\n if (!looksLikeJson && !isJsonContentType) {\n // Return raw text when it doesn't look like JSON (e.g., HTML error pages).\n return bodyText;\n }\n\n return JSON.parse(trimmed) as unknown;\n }\n\n /**\n * Execute HTTP request using Angular's HttpClient.\n *\n * @param config - Request configuration\n * @returns Response with parsed data\n * @throws NAuthClientError if request fails\n */\n async request<T>(config: HttpRequest): Promise<HttpResponse<T>> {\n try {\n // Use Angular's HttpClient - goes through ALL interceptors.\n // IMPORTANT: Use responseType 'text' to avoid raw JSON.parse crashes when\n // the backend returns HTML (seen in some proxy/SSR/misroute setups).\n const res = await firstValueFrom(\n this.http.request(config.method, config.url, {\n body: config.body,\n headers: config.headers,\n withCredentials: config.credentials === 'include',\n observe: 'response',\n responseType: 'text',\n }),\n );\n\n const contentType = res.headers?.get('content-type');\n const parsed = this.parseJsonBody(res.body ?? '', contentType);\n\n return {\n data: parsed as T,\n status: res.status,\n headers: {}, // Reserved for future header passthrough if needed\n };\n } catch (error) {\n if (error instanceof HttpErrorResponse) {\n // Convert Angular's HttpErrorResponse to NAuthClientError.\n // When using responseType 'text', `error.error` is typically a string.\n const contentType = error.headers?.get('content-type') ?? null;\n const rawBody = typeof error.error === 'string' ? error.error : '';\n const parsedError = this.parseJsonBody(rawBody, contentType);\n\n const errorData =\n typeof parsedError === 'object' && parsedError !== null ? (parsedError as Record<string, unknown>) : {};\n const code =\n typeof errorData['code'] === 'string' ? (errorData['code'] as NAuthErrorCode) : NAuthErrorCode.INTERNAL_ERROR;\n const message =\n typeof errorData['message'] === 'string'\n ? (errorData['message'] as string)\n : typeof parsedError === 'string' && parsedError.trim()\n ? parsedError\n : error.message || `Request failed with status ${error.status}`;\n const timestamp = typeof errorData['timestamp'] === 'string' ? (errorData['timestamp'] as string) : undefined;\n const details =\n typeof errorData['details'] === 'object' ? (errorData['details'] as Record<string, unknown>) : undefined;\n\n throw new NAuthClientError(code, message, {\n statusCode: error.status,\n timestamp,\n details,\n isNetworkError: error.status === 0, // Network error (no response from server)\n });\n }\n\n // Re-throw non-HTTP errors as an SDK error so consumers don't see raw parser crashes.\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new NAuthClientError(NAuthErrorCode.INTERNAL_ERROR, message, {\n statusCode: 0,\n isNetworkError: true,\n });\n }\n }\n}\n","import { Injectable, Inject, PLATFORM_ID, Optional, InjectionToken } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n\n/**\n * Detects the current platform environment\n */\ntype Platform = 'web' | 'capacitor-webview' | 'capacitor-native' | 'ssr';\n\n/**\n * reCAPTCHA version type\n */\ntype RecaptchaVersion = 'v2' | 'v3' | 'enterprise';\n\n/**\n * reCAPTCHA configuration for RecaptchaService\n * \n * Internal configuration interface used by RecaptchaService.\n * Use RecaptchaAngularConfig from tokens.ts for app configuration.\n */\nexport interface RecaptchaServiceConfig {\n enabled: boolean;\n version: RecaptchaVersion;\n siteKey: string;\n action?: string;\n autoLoadScript?: boolean;\n language?: string;\n}\n\n/**\n * Injection token for reCAPTCHA configuration\n */\nexport const RECAPTCHA_CONFIG = new InjectionToken<RecaptchaServiceConfig | undefined>('RECAPTCHA_CONFIG', {\n providedIn: 'root',\n factory: () => undefined,\n});\n\n/**\n * Google reCAPTCHA service for Angular applications.\n *\n * Provides lazy loading of reCAPTCHA script and platform-aware token generation.\n * Automatically detects platform (web, Capacitor WebView, Capacitor native, SSR)\n * and skips reCAPTCHA in environments where it's not supported or needed.\n *\n * Features:\n * - Lazy script loading (only loads when needed)\n * - v2 (checkbox) and v3 (invisible) support\n * - Platform detection (web, Capacitor, SSR)\n * - Automatic skip for Capacitor native mode\n * - Automatic skip for SSR\n *\n * @example v3 Automatic Mode\n * ```typescript\n * constructor(private recaptcha: RecaptchaService) {}\n *\n * async login() {\n * const token = await this.recaptcha.execute('login');\n * await this.auth.login(email, password, token);\n * }\n * ```\n *\n * @example v2 Manual Mode\n * ```typescript\n * ngOnInit() {\n * this.recaptcha.render('recaptcha-container', (token) => {\n * this.recaptchaToken = token;\n * });\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class RecaptchaService {\n private scriptLoaded = false;\n private scriptLoading: Promise<void> | null = null;\n private platform: Platform;\n private widgetId: number | null = null;\n\n constructor(\n @Inject(PLATFORM_ID) private platformId: string,\n @Optional() @Inject(RECAPTCHA_CONFIG) private config?: RecaptchaServiceConfig,\n ) {\n this.platform = this.detectPlatform();\n \n // Auto-preload script for v3/Enterprise so it's ready before first login/signup\n // No-op when disabled, shouldSkip, or v2 (v2 renders on-demand)\n if (this.config?.enabled && (this.config.version === 'v3' || this.config.version === 'enterprise')) {\n if (!this.shouldSkip()) {\n this.loadScript().catch(() => {\n // Silently fail - execute() will handle errors when called\n });\n }\n }\n }\n\n // ============================================================================\n // Platform Detection\n // ============================================================================\n\n /**\n * Detect the current platform environment.\n *\n * Detection priority:\n * 1. SSR (not in browser) → 'ssr'\n * 2. Capacitor native (no web view) → 'capacitor-native'\n * 3. Capacitor WebView → 'capacitor-webview'\n * 4. Web browser → 'web'\n *\n * @returns Detected platform type\n *\n * @example\n * ```typescript\n * const platform = this.detectPlatform();\n * if (platform === 'capacitor-native') {\n * // Skip reCAPTCHA, use device attestation\n * }\n * ```\n */\n private detectPlatform(): Platform {\n // SSR detection\n if (!isPlatformBrowser(this.platformId)) {\n return 'ssr';\n }\n\n // Capacitor detection (window.Capacitor exists)\n const windowRef = window as { Capacitor?: { isNativePlatform?: () => boolean } };\n\n if (windowRef.Capacitor) {\n // Capacitor native (iOS/Android app)\n if (typeof windowRef.Capacitor.isNativePlatform === 'function' && windowRef.Capacitor.isNativePlatform()) {\n return 'capacitor-native';\n }\n // Capacitor WebView\n return 'capacitor-webview';\n }\n\n return 'web';\n }\n\n /**\n * Get the current platform.\n *\n * @returns Current platform type\n */\n getPlatform(): Platform {\n return this.platform;\n }\n\n /**\n * Check if reCAPTCHA should be skipped for current platform.\n *\n * Skips for:\n * - SSR (no window object)\n * - Capacitor native (use device attestation instead)\n *\n * @returns True if should skip reCAPTCHA\n */\n shouldSkip(): boolean {\n return this.platform === 'ssr' || this.platform === 'capacitor-native';\n }\n\n // ============================================================================\n // Script Loading\n // ============================================================================\n\n /**\n * Load Google reCAPTCHA script if not already loaded.\n *\n * Script URL format:\n * - v2: https://www.google.com/recaptcha/api.js\n * - v3: https://www.google.com/recaptcha/api.js?render={siteKey}\n * - Enterprise: https://www.google.com/recaptcha/enterprise.js?render={siteKey}\n *\n * @returns Promise that resolves when script is loaded\n *\n * @throws Error if config is missing or script fails to load\n */\n async loadScript(): Promise<void> {\n // Skip in SSR or Capacitor native\n if (this.shouldSkip()) {\n return;\n }\n\n // Skip if disabled\n if (!this.config?.enabled) {\n return;\n }\n\n // Already loaded\n if (this.scriptLoaded) {\n return;\n }\n\n // Already loading (return existing promise)\n if (this.scriptLoading) {\n return this.scriptLoading;\n }\n\n // Validate config\n if (!this.config.siteKey) {\n throw new Error('[RecaptchaService] Site key is required');\n }\n\n // Start loading\n this.scriptLoading = this.injectScript();\n\n try {\n await this.scriptLoading;\n this.scriptLoaded = true;\n } finally {\n this.scriptLoading = null;\n }\n }\n\n /**\n * Inject the reCAPTCHA script into the DOM.\n *\n * @returns Promise that resolves when script loads\n */\n private injectScript(): Promise<void> {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.async = true;\n script.defer = true;\n\n // Set script URL based on version\n if (this.config!.version === 'enterprise') {\n script.src = `https://www.google.com/recaptcha/enterprise.js?render=${this.config!.siteKey}`;\n } else if (this.config!.version === 'v3') {\n script.src = `https://www.google.com/recaptcha/api.js?render=${this.config!.siteKey}`;\n } else {\n // v2 - load without render parameter\n let url = 'https://www.google.com/recaptcha/api.js';\n if (this.config!.language) {\n url += `?hl=${this.config!.language}`;\n }\n script.src = url;\n }\n\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('[RecaptchaService] Failed to load reCAPTCHA script'));\n\n document.head.appendChild(script);\n });\n }\n\n // ============================================================================\n // v3/Enterprise Methods (Invisible Challenge)\n // ============================================================================\n\n /**\n * Execute reCAPTCHA v3/Enterprise challenge (invisible).\n *\n * Automatically loads script if needed and generates a token.\n * Skips automatically for SSR and Capacitor native.\n *\n * @param action - Action name for v3 analytics (e.g., 'login', 'signup')\n * @returns Promise resolving to reCAPTCHA token, or undefined if skipped\n *\n * @throws Error if version is v2, config missing, or execution fails\n *\n * @example\n * ```typescript\n * const token = await this.recaptcha.execute('login');\n * if (token) {\n * await this.auth.login(email, password, token);\n * }\n * ```\n */\n async execute(action?: string): Promise<string | undefined> {\n // Skip for platforms that don't support reCAPTCHA\n if (this.shouldSkip()) {\n return undefined;\n }\n\n // Skip if disabled\n if (!this.config?.enabled) {\n return undefined;\n }\n\n // v2 requires manual render\n if (this.config.version === 'v2') {\n throw new Error('[RecaptchaService] execute() is only for v3/Enterprise. Use render() for v2.');\n }\n\n // Load script if needed\n await this.loadScript();\n\n // Get grecaptcha object\n const grecaptcha = (window as { grecaptcha?: { execute?: (siteKey: string, options: { action: string }) => Promise<string>; enterprise?: { execute?: (siteKey: string, options: { action: string }) => Promise<string> } } }).grecaptcha;\n\n if (!grecaptcha) {\n throw new Error('[RecaptchaService] grecaptcha is not loaded');\n }\n\n // Execute reCAPTCHA\n const actionName = action || this.config.action || 'submit';\n\n try {\n if (this.config.version === 'enterprise' && grecaptcha.enterprise?.execute) {\n return await grecaptcha.enterprise.execute(this.config.siteKey, { action: actionName });\n } else if (grecaptcha.execute) {\n return await grecaptcha.execute(this.config.siteKey, { action: actionName });\n } else {\n throw new Error('[RecaptchaService] grecaptcha.execute is not available');\n }\n } catch (error: unknown) {\n throw new Error(`[RecaptchaService] Failed to execute reCAPTCHA: ${error instanceof Error ? error.message : 'unknown error'}`);\n }\n }\n\n // ============================================================================\n // v2 Methods (Visible Checkbox)\n // ============================================================================\n\n /**\n * Render reCAPTCHA v2 checkbox widget.\n *\n * @param containerId - DOM element ID or element to render in\n * @param callback - Callback when user completes challenge\n * @returns Promise resolving to widget ID\n *\n * @throws Error if version is not v2, config missing, or render fails\n *\n * @example\n * ```typescript\n * ngAfterViewInit() {\n * this.recaptcha.render('recaptcha-container', (token) => {\n * this.recaptchaToken = token;\n * this.loginForm.patchValue({ recaptchaToken: token });\n * });\n * }\n * ```\n */\n async render(containerId: string, callback: (token: string) => void): Promise<number> {\n // Skip for platforms that don't support reCAPTCHA\n if (this.shouldSkip()) {\n throw new Error('[RecaptchaService] reCAPTCHA v2 is not supported in SSR or Capacitor native');\n }\n\n // Skip if disabled\n if (!this.config?.enabled) {\n throw new Error('[RecaptchaService] reCAPTCHA is not enabled');\n }\n\n // Only for v2\n if (this.config.version !== 'v2') {\n throw new Error('[RecaptchaService] render() is only for v2. Use execute() for v3/Enterprise.');\n }\n\n // Load script if needed\n await this.loadScript();\n\n // Get grecaptcha object\n const grecaptcha = (window as { grecaptcha?: { render?: (container: string, options: { sitekey: string; callback: (token: string) => void }) => number } }).grecaptcha;\n\n if (!grecaptcha?.render) {\n throw new Error('[RecaptchaService] grecaptcha.render is not available');\n }\n\n // Render widget\n try {\n this.widgetId = grecaptcha.render(containerId, {\n sitekey: this.config.siteKey,\n callback: callback,\n });\n return this.widgetId;\n } catch (error: unknown) {\n throw new Error(`[RecaptchaService] Failed to render reCAPTCHA: ${error instanceof Error ? error.message : 'unknown error'}`);\n }\n }\n\n /**\n * Get response token from v2 widget.\n *\n * @param widgetId - Widget ID (optional, uses last rendered widget if not provided)\n * @returns reCAPTCHA token or null if not completed\n *\n * @example\n * ```typescript\n * const token = this.recaptcha.getResponse();\n * if (token) {\n * await this.auth.login(email, password, token);\n * }\n * ```\n */\n getResponse(widgetId?: number): string | null {\n const grecaptcha = (window as { grecaptcha?: { getResponse?: (widgetId?: number) => string } }).grecaptcha;\n\n if (!grecaptcha?.getResponse) {\n return null;\n }\n\n const id = widgetId !== undefined ? widgetId : this.widgetId ?? undefined;\n return grecaptcha.getResponse(id) || null;\n }\n\n /**\n * Reset v2 widget (clear response).\n *\n * @param widgetId - Widget ID (optional, uses last rendered widget if not provided)\n *\n * @example\n * ```typescript\n * // After failed login\n * this.recaptcha.reset();\n * ```\n */\n reset(widgetId?: number): void {\n const grecaptcha = (window as { grecaptcha?: { reset?: (widgetId?: number) => void } }).grecaptcha;\n\n if (!grecaptcha?.reset) {\n return;\n }\n\n const id = widgetId !== undefined ? widgetId : this.widgetId ?? undefined;\n grecaptcha.reset(id);\n }\n}\n","import { Inject, Injectable, Optional } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport { filter } from 'rxjs/operators';\nimport { NAUTH_CLIENT_CONFIG } from './tokens';\nimport { AngularHttpAdapter } from './http-adapter';\nimport { RecaptchaService } from '../lib/recaptcha.service';\nimport {\n NAuthClient,\n NAuthClientConfig,\n AuthResponseContext,\n ChallengeResponse,\n AuthResponse,\n TokenResponse,\n AuthUser,\n ConfirmForgotPasswordResponse,\n ForgotPasswordResponse,\n ResetPasswordWithCodeResponse,\n UpdateProfileRequest,\n GetChallengeDataResponse,\n GetSetupDataResponse,\n MFAStatus,\n MFADevice,\n AuthEvent,\n SocialProvider,\n SocialLoginOptions,\n LinkedAccountsResponse,\n SocialVerifyRequest,\n AuditHistoryResponse,\n AdminOperations,\n} from '@nauth-toolkit/client';\n\n/**\n * Angular wrapper around NAuthClient that provides promise-based auth methods and reactive state.\n *\n * This service provides:\n * - Reactive state (currentUser$, isAuthenticated$, challenge$)\n * - All core auth methods as Promises (login, signup, logout, refresh)\n * - Profile management (getProfile, updateProfile, changePassword)\n * - Challenge flow methods (respondToChallenge, resendCode)\n * - MFA management (getMfaStatus, setupMfaDevice, etc.)\n * - Social authentication and account linking\n * - Device trust management\n * - Audit history\n *\n * @example\n * ```typescript\n * constructor(private auth: AuthService) {}\n *\n * // Reactive state\n * this.auth.currentUser$.subscribe(user => ...);\n * this.auth.isAuthenticated$.subscribe(isAuth => ...);\n *\n * // Auth operations with async/await\n * const response = await this.auth.login(email, password);\n *\n * // Profile management\n * await this.auth.changePassword(oldPassword, newPassword);\n * const user = await this.auth.updateProfile({ firstName: 'John' });\n *\n * // MFA operations\n * const status = await this.auth.getMfaStatus();\n * ```\n */\n@Injectable()\nexport class AuthService {\n private readonly client: NAuthClient;\n private readonly config: NAuthClientConfig;\n private readonly currentUserSubject = new BehaviorSubject<AuthUser | null>(null);\n private readonly isAuthenticatedSubject = new BehaviorSubject<boolean>(false);\n private readonly challengeSubject = new BehaviorSubject<AuthResponse | null>(null);\n private readonly authEventsSubject = new Subject<AuthEvent>();\n private initialized = false;\n\n /**\n * @param config - Injected client configuration (required)\n * @param httpAdapter - Angular HTTP adapter for making requests (required)\n * @param router - Angular Router (optional, automatically used for navigation if available)\n * @param recaptchaService - RecaptchaService (optional, for automatic token generation)\n */\n constructor(\n @Inject(NAUTH_CLIENT_CONFIG) config: NAuthClientConfig,\n httpAdapter: AngularHttpAdapter,\n @Optional() private router?: Router,\n @Optional() private recaptchaService?: RecaptchaService,\n ) {\n this.config = config;\n\n // Use provided httpAdapter (from config or injected)\n const adapter = config.httpAdapter ?? httpAdapter;\n if (!adapter) {\n throw new Error(\n 'HttpAdapter not found. Either provide httpAdapter in NAUTH_CLIENT_CONFIG or ensure HttpClient is available.',\n );\n }\n\n // ============================================================================\n // Automatic Angular Router integration\n // ============================================================================\n // If Router is available and no custom navigationHandler is provided,\n // automatically use Angular Router's navigateByUrl() to prevent page refreshes\n const navigationHandler =\n config.navigationHandler ??\n (this.router\n ? async (url: string): Promise<void> => {\n await this.router!.navigateByUrl(url);\n }\n : undefined);\n\n // ============================================================================\n // IMPORTANT: Challenge-state hydration BEFORE navigation (Angular guard safety)\n // ============================================================================\n // WHY: `NAuthClient.login()` auto-navigates via ChallengeRouter *before* returning.\n // The Angular sample app uses a synchronous guard (`challengeRouteGuard`) that\n // reads the current challenge via `AuthService.getCurrentChallenge()` (backed by\n // `challengeSubject.value`). If navigation happens before `challengeSubject` is\n // updated, the guard incorrectly redirects back to `/login`.\n //\n // Fix: intercept the SDK's auto-navigation hook (`onAuthResponse`), publish the\n // challenge state immediately, then perform default navigation (or delegate to\n // the user's custom `onAuthResponse` if provided).\n const userOnAuthResponse = config.onAuthResponse;\n\n this.client = new NAuthClient({\n ...config,\n httpAdapter: adapter,\n navigationHandler,\n onAuthResponse: async (response: AuthResponse, context: AuthResponseContext): Promise<void> => {\n // Ensure guards can synchronously see the active challenge before navigation.\n this.updateChallengeState(response);\n\n // If the consumer provided their own handler, let them take full control.\n if (userOnAuthResponse) {\n await userOnAuthResponse(response, context);\n return;\n }\n\n // Default navigation behavior (matches ChallengeRouter.handleAuthResponse)\n const router = this.client.getChallengeRouter();\n if (response.challengeName) {\n await router.navigateToChallenge(response);\n return;\n }\n\n // Prefer appState provided via context (social redirect guard / exchange flow).\n // IMPORTANT: Do not consume/clear persisted OAuth state here; leave it available\n // for consumers via getLastOauthState().\n await router.navigateToSuccess(context.appState ? { appState: context.appState } : undefined, context);\n },\n onAuthStateChange: (user: AuthUser | null) => {\n this.currentUserSubject.next(user);\n this.isAuthenticatedSubject.next(Boolean(user));\n config.onAuthStateChange?.(user);\n },\n });\n\n // Forward all client events to Observable stream\n this.client.on('*', (event: AuthEvent) => {\n this.authEventsSubject.next(event);\n });\n\n // Auto-initialize on construction (hydrate from storage)\n this.initialize();\n }\n\n // ============================================================================\n // Reactive State Observables\n // ============================================================================\n\n /**\n * Current user observable.\n */\n get currentUser$(): Observable<AuthUser | null> {\n return this.currentUserSubject.asObservable();\n }\n\n /**\n * Authenticated state observable.\n */\n get isAuthenticated$(): Observable<boolean> {\n return this.isAuthenticatedSubject.asObservable();\n }\n\n /**\n * Current challenge observable (for reactive challenge navigation).\n */\n get challenge$(): Observable<AuthResponse | null> {\n return this.challengeSubject.asObservable();\n }\n\n /**\n * Authentication events stream.\n * Emits all auth lifecycle events for custom logic, analytics, or UI updates.\n */\n get authEvents$(): Observable<AuthEvent> {\n return this.authEventsSubject.asObservable();\n }\n\n /**\n * Successful authentication events stream.\n * Emits when user successfully authenticates (login, signup, social auth).\n */\n get authSuccess$(): Observable<AuthEvent> {\n return this.authEventsSubject.pipe(filter((e) => e.type === 'auth:success'));\n }\n\n /**\n * Authentication error events stream.\n * Emits when authentication fails (login error, OAuth error, etc.).\n */\n get authError$(): Observable<AuthEvent> {\n return this.authEventsSubject.pipe(filter((e) => e.type === 'auth:error' || e.type === 'oauth:error'));\n }\n\n // ============================================================================\n // Sync State Accessors (for guards, templates)\n // ============================================================================\n\n /**\n * Check if authenticated (sync, uses cached state).\n */\n isAuthenticated(): boolean {\n return this.client.isAuthenticatedSync();\n }\n\n /**\n * Get current user (sync, uses cached state).\n */\n getCurrentUser(): AuthUser | null {\n return this.client.getCurrentUser();\n }\n\n /**\n * Get current challenge (sync).\n */\n getCurrentChallenge(): AuthResponse | null {\n return this.challengeSubject.value;\n }\n\n /**\n * Get challenge router for manual navigation control.\n * Useful for guards that need to handle errors or build custom URLs.\n *\n * @returns ChallengeRouter instance\n *\n * @example\n * ```typescript\n * const router = this.auth.getChallengeRouter();\n * await router.navigateToError('oauth');\n * ```\n */\n getChallengeRouter() {\n return this.client.getChallengeRouter();\n }\n\n // ============================================================================\n // Core Auth Methods\n // ============================================================================\n\n /**\n * Login with identifier and password.\n *\n * Automatically generates reCAPTCHA token if configured (v3 only).\n * For v2 manual mode, pass the token explicitly.\n *\n * @param identifier - User email or username\n * @param password - User password\n * @param recaptchaToken - Optional reCAPTCHA token (for v2 manual mode or when auto-generation is disabled)\n * @returns Promise with auth response or challenge\n *\n * @example Basic Login\n * ```typescript\n * const response = await this.auth.login('user@example.com', 'password');\n * ```\n *\n * @example With Manual reCAPTCHA (v2)\n * ```typescript\n * const response = await this.auth.login('user@example.com', 'password', recaptchaToken);\n * ```\n */\n async login(identifier: string, password: string, recaptchaToken?: string): Promise<AuthResponse> {\n const token = await this.getRecaptchaToken(recaptchaToken, 'login');\n const res = await this.client.login(identifier, password, token);\n return this.updateChallengeState(res);\n }\n\n /**\n * Signup with credentials.\n *\n * Automatically generates reCAPTCHA token if configured (v3 only).\n * For v2 manual mode, include token in payload.\n *\n * @param payload - Signup request payload\n * @returns Promise with auth response or challenge\n *\n * @example Basic Signup\n * ```typescript\n * const response = await this.auth.signup({\n * email: 'new@example.com',\n * password: 'SecurePass123!',\n * firstName: 'John',\n * });\n * ```\n *\n * @example With Manual reCAPTCHA (v2)\n * ```typescript\n * const response = await this.auth.signup({\n * email: 'new@example.com',\n * password: 'SecurePass123!',\n * recaptchaToken: token,\n * });\n * ```\n */\n async signup(payload: Parameters<NAuthClient['signup']>[0]): Promise<AuthResponse> {\n // Auto-generate reCAPTCHA token for v3 if configured and not already provided\n const payloadWithRecaptcha = payload as { recaptchaToken?: string };\n\n if (!payloadWithRecaptcha.recaptchaToken) {\n const token = await this.getRecaptchaToken(undefined, 'signup');\n if (token) {\n payload = { ...payload, recaptchaToken: token };\n }\n }\n\n const res = await this.client.signup(payload);\n return this.updateChallengeState(res);\n }\n\n /**\n * Logout current session.\n *\n * @param forgetDevice - If true, removes device trust\n *\n * @example\n * ```typescript\n * await this.auth.logout();\n * ```\n */\n async logout(forgetDevice?: boolean): Promise<void> {\n await this.client.logout(forgetDevice);\n this.challengeSubject.next(null);\n // Explicitly update auth state after logout\n this.currentUserSubject.next(null);\n this.isAuthenticatedSubject.next(false);\n\n // Clear CSRF token cookie if in cookies mode\n // Note: Backend should clear httpOnly cookies, but we clear non-httpOnly ones\n if (this.config.tokenDelivery === 'cookies' && typeof document !== 'undefined') {\n const csrfCookieName = this.config.csrf?.cookieName ?? 'nauth_csrf_token';\n // Extract domain from baseUrl if possible\n try {\n const url = new URL(this.config.baseUrl);\n document.cookie = `${csrfCookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${url.hostname}`;\n // Also try without domain (for localhost)\n document.cookie = `${csrfCookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n } catch {\n // Fallback if baseUrl parsing fails\n document.cookie = `${csrfCookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n }\n }\n }\n\n /**\n * Logout all sessions.\n *\n * Revokes all active sessions for the current user across all devices.\n * Optionally revokes all trusted devices if forgetDevices is true.\n *\n * @param forgetDevices - If true, also revokes all trusted devices (default: false)\n * @returns Promise with number of sessions revoked\n *\n * @example\n * ```typescript\n * const result = await this.auth.logoutAll();\n * console.log(`Revoked ${result.revokedCount} sessions`);\n * ```\n */\n async logoutAll(forgetDevices?: boolean): Promise<{ revokedCount: number }> {\n const res = await this.client.logoutAll(forgetDevices);\n this.challengeSubject.next(null);\n // Explicitly update auth state after logout\n this.currentUserSubject.next(null);\n this.isAuthenticatedSubject.next(false);\n return res;\n }\n\n /**\n * Refresh tokens.\n *\n * @returns Promise with new tokens\n *\n * @example\n * ```typescript\n * const tokens = await this.auth.refresh();\n * ```\n */\n async refresh(): Promise<TokenResponse> {\n return this.client.refreshTokens();\n }\n\n // ============================================================================\n // Account Recovery (Forgot Password)\n // ============================================================================\n\n /**\n * Request a password reset code (forgot password).\n *\n * @param identifier - User email, username, or phone\n * @returns Promise with password reset response\n *\n * @example\n * ```typescript\n * await this.auth.forgotPassword('user@example.com');\n * ```\n */\n async forgotPassword(identifier: string): Promise<ForgotPasswordResponse> {\n return this.client.forgotPassword(identifier);\n }\n\n /**\n * Confirm a password reset code and set a new password.\n *\n * @param identifier - User email, username, or phone\n * @param code - One-time reset code\n * @param newPassword - New password\n * @returns Promise with confirmation response\n *\n * @example\n * ```typescript\n * await this.auth.confirmForgotPassword('user@example.com', '123456', 'NewPass123!');\n * ```\n */\n async confirmForgotPassword(\n identifier: string,\n code: string,\n newPassword: string,\n ): Promise<ConfirmForgotPasswordResponse> {\n return this.client.confirmForgotPassword(identifier, code, newPassword);\n }\n\n /**\n * Reset password with code or token (generic method for both admin and user-initiated resets).\n *\n * Accepts either:\n * - code: Short numeric code from email/SMS (6-10 digits)\n * - token: Long hex token from reset link (64 chars)\n *\n * @param identifier - User identifier (email, username, phone)\n * @param codeOrToken - Verification code OR token from link\n * @param newPassword - New password\n * @returns Promise with success response\n *\n * @example\n * ```typescript\n * // With code from email\n * await this.auth.resetPasswordWithCode('user@example.com', '123456', 'NewPass123!');\n *\n * // With token from link\n * await this.auth.resetPasswordWithCode('user@example.com', '64-char-token', 'NewPass123!');\n * ```\n */\n async resetPasswordWithCode(\n identifier: string,\n codeOrToken: string,\n newPassword: string,\n ): Promise<ResetPasswordWithCodeResponse> {\n return this.client.resetPasswordWithCode(identifier, codeOrToken, newPassword);\n }\n\n /**\n * Change user password (requires current password).\n *\n * @param oldPassword - Current password\n * @param newPassword - New password (must meet requirements)\n * @returns Promise that resolves when password is changed\n *\n * @example\n * ```typescript\n * await this.auth.changePassword('oldPassword123', 'newSecurePassword456!');\n * ```\n */\n async changePassword(oldPassword: string, newPassword: string): Promise<void> {\n return this.client.changePassword(oldPassword, newPassword);\n }\n\n // ============================================================================\n // Profile Management\n // ============================================================================\n\n /**\n * Get current user profile.\n *\n * @returns Promise of current user profile\n *\n * @example\n * ```typescript\n * const user = await this.auth.getProfile();\n * console.log('User profile:', user);\n * ```\n */\n async getProfile(): Promise<AuthUser> {\n const user = await this.client.getProfile();\n // Update local state when profile is fetched\n this.currentUserSubject.next(user);\n return user;\n }\n\n /**\n * Update user profile.\n *\n * @param updates - Profile fields to update\n * @returns Promise of updated user profile\n *\n * @example\n * ```typescript\n * const user = await this.auth.updateProfile({ firstName: 'John', lastName: 'Doe' });\n * console.log('Profile updated:', user);\n * ```\n */\n async updateProfile(updates: UpdateProfileRequest): Promise<AuthUser> {\n const user = await this.client.updateProfile(updates);\n // Update local state when profile is updated\n this.currentUserSubject.next(user);\n return user;\n }\n\n // ============================================================================\n // Challenge Flow Methods (Essential for any auth flow)\n // ============================================================================\n\n /**\n * Respond to a challenge (VERIFY_EMAIL, VERIFY_PHONE, MFA_REQUIRED, etc.).\n *\n * @param response - Challenge response data\n * @returns Promise with auth response or next challenge\n *\n * @example\n * ```typescript\n * const result = await this.auth.respondToChallenge({\n * session: challengeSession,\n * type: 'VERIFY_EMAIL',\n * code: '123456',\n * });\n * ```\n */\n async respondToChallenge(response: ChallengeResponse): Promise<AuthResponse> {\n const res = await this.client.respondToChallenge(response);\n return this.updateChallengeState(res);\n }\n\n /**\n * Resend challenge code.\n *\n * @param session - Challenge session token\n * @returns Promise with destination information\n *\n * @example\n * ```typescript\n * const result = await this.auth.resendCode(session);\n * console.log('Code sent to:', result.destination);\n * ```\n */\n async resendCode(session: string): Promise<{ destination: string }> {\n return this.client.resendCode(session);\n }\n\n /**\n * Get MFA setup data (for MFA_SETUP_REQUIRED challenge).\n *\n * Returns method-specific setup information:\n * - TOTP: { secret, qrCode, manualEntryKey }\n * - SMS: { maskedPhone }\n * - Email: { maskedEmail }\n * - Passkey: WebAuthn registration options\n *\n * @param session - Challenge session token\n * @param method - MFA method to set up\n * @returns Promise of setup data response\n *\n * @example\n * ```typescript\n * const setupData = await this.auth.getSetupData(session, 'totp');\n * console.log('QR Code:', setupData.setupData.qrCode);\n * ```\n */\n async getSetupData(session: string, method: string): Promise<GetSetupDataResponse> {\n return this.client.getSetupData(session, method as Parameters<NAuthClient['getSetupData']>[1]);\n }\n\n /**\n * Get MFA challenge data (for MFA_REQUIRED challenge - e.g., passkey options).\n *\n * @param session - Challenge session token\n * @param method - Challenge method\n * @returns Promise of challenge data response\n *\n * @example\n * ```typescript\n * const challengeData = await this.auth.getChallengeData(session, 'passkey');\n * ```\n */\n async getChallengeData(session: string, method: string): Promise<GetChallengeDataResponse> {\n return this.client.getChallengeData(session, method as Parameters<NAuthClient['getChallengeData']>[1]);\n }\n\n /**\n * Clear stored challenge (when navigating away from challenge flow).\n *\n * @returns Promise that resolves when challenge is cleared\n *\n * @example\n * ```typescript\n * await this.auth.clearChallenge();\n * ```\n */\n async clearChallenge(): Promise<void> {\n await this.client.clearStoredChallenge();\n this.challengeSubject.next(null);\n }\n\n /**\n * Get current access token (JSON mode only).\n *\n * This is primarily useful for consumers using Angular `HttpClient` directly\n * (outside of the SDK methods) and relying on an interceptor to attach Bearer tokens.\n *\n * @returns Access token, or null if not available\n *\n * @example\n * ```typescript\n * const token = await this.auth.getAccessToken();\n * ```\n */\n async getAccessToken(): Promise<string | null> {\n return await this.client.getAccessToken();\n }\n\n // ============================================================================\n // Social Authentication\n // ============================================================================\n\n /**\n * Initiate social OAuth login flow.\n * Redirects the browser to backend `/auth/social/:provider/redirect`.\n *\n * @param provider - Social provider ('google', 'apple', 'facebook')\n * @param options - Optional redirect options\n * @returns Promise that resolves when redirect starts\n *\n * @example\n * ```typescript\n * await this.auth.loginWithSocial('google', { returnTo: '/auth/callback' });\n * ```\n */\n async loginWithSocial(provider: SocialProvider, options?: SocialLoginOptions): Promise<void> {\n return this.client.loginWithSocial(provider, options);\n }\n\n /**\n * Exchange an exchangeToken (from redirect callback URL) into an AuthResponse.\n *\n * Used for `tokenDelivery: 'json'` or hybrid flows where the backend redirects back\n * with `exchangeToken` instead of setting cookies.\n *\n * @param exchangeToken - One-time exchange token from the callback URL\n * @returns Promise of AuthResponse\n *\n * @example\n * ```typescript\n * const response = await this.auth.exchangeSocialRedirect(exchangeToken);\n * ```\n */\n async exchangeSocialRedirect(exchangeToken: string): Promise<AuthResponse> {\n const res = await this.client.exchangeSocialRedirect(exchangeToken);\n return this.updateChallengeState(res);\n }\n\n /**\n * Verify native social token (mobile).\n *\n * @param request - Social verification request with provider and token\n * @returns Promise of AuthResponse\n *\n * @example\n * ```typescript\n * const result = await this.auth.verifyNativeSocial({\n * provider: 'google',\n * idToken: nativeIdToken,\n * });\n * ```\n */\n async verifyNativeSocial(request: SocialVerifyRequest): Promise<AuthResponse> {\n const res = await this.client.verifyNativeSocial(request);\n return this.updateChallengeState(res);\n }\n\n /**\n * Get linked social accounts.\n *\n * @returns Promise of linked accounts response\n *\n * @example\n * ```typescript\n * const accounts = await this.auth.getLinkedAccounts();\n * console.log('Linked providers:', accounts.providers);\n * ```\n */\n async getLinkedAccounts(): Promise<LinkedAccountsResponse> {\n return this.client.getLinkedAccounts();\n }\n\n /**\n * Link social account.\n *\n * @param provider - Social provider to link\n * @param code - OAuth authorization code\n * @param state - OAuth state parameter\n * @returns Promise with success message\n *\n * @example\n * ```typescript\n * await this.auth.linkSocialAccount('google', code, state);\n * ```\n */\n async linkSocialAccount(provider: string, code: string, state: string): Promise<{ message: string }> {\n return this.client.linkSocialAccount(provider, code, state);\n }\n\n /**\n * Unlink social account.\n *\n * @param provider - Social provider to unlink\n * @returns Promise with success message\n *\n * @example\n * ```typescript\n * await this.auth.unlinkSocialAccount('google');\n * ```\n */\n async unlinkSocialAccount(provider: string): Promise<{ message: string }> {\n return this.client.unlinkSocialAccount(provider);\n }\n\n /**\n * Get the last OAuth appState from social redirect callback.\n *\n * Returns the appState that was stored during the most recent social\n * login redirect callback. This is useful for restoring UI state,\n * applying invite codes, or tracking referral information.\n *\n * The state is automatically cleared after retrieval to prevent reuse.\n *\n * @returns The stored appState, or null if none exists\n *\n * @example\n * ```typescript\n * const appState = await this.auth.getLastOauthState();\n * if (appState) {\n * // Apply invite code or restore UI state\n * console.log('OAuth state:', appState);\n * }\n * ```\n */\n async getLastOauthState(): Promise<string | null> {\n return this.client.getLastOauthState();\n }\n\n // ============================================================================\n // MFA Management\n // ============================================================================\n\n /**\n * Get MFA status for the current user.\n *\n * @returns Promise of MFA status\n *\n * @example\n * ```typescript\n * const status = await this.auth.getMfaStatus();\n * console.log('MFA enabled:', status.enabled);\n * ```\n */\n async getMfaStatus(): Promise<MFAStatus> {\n return this.client.getMfaStatus();\n }\n\n /**\n * Get MFA devices for the current user.\n *\n * @returns Promise of MFA devices array\n *\n * @example\n * ```typescript\n * const devices = await this.auth.getMfaDevices();\n * ```\n */\n async getMfaDevices(): Promise<MFADevice[]> {\n return this.client.getMfaDevices() as Promise<MFADevice[]>;\n }\n\n /**\n * Setup MFA device (authenticated user).\n *\n * @param method - MFA method to set up\n * @returns Promise of setup data\n *\n * @example\n * ```typescript\n * const setupData = await this.auth.setupMfaDevice('totp');\n * ```\n */\n async setupMfaDevice(method: string): Promise<unknown> {\n return this.client.setupMfaDevice(method);\n }\n\n /**\n * Verify MFA setup (authenticated user).\n *\n * @param method - MFA method\n * @param setupData - Setup data from setupMfaDevice\n * @param deviceName - Optional device name\n * @returns Promise with device ID\n *\n * @example\n * ```typescript\n * const result = await this.auth.verifyMfaSetup('totp', { code: '123456' }, 'My Phone');\n * ```\n */\n async verifyMfaSetup(\n method: string,\n setupData: Record<string, unknown>,\n deviceName?: string,\n ): Promise<{ deviceId: number }> {\n return this.client.verifyMfaSetup(method, setupData, deviceName);\n }\n\n /**\n * Remove MFA device.\n *\n * @param method - MFA method to remove\n * @returns Promise with success message\n *\n * @example\n * ```typescript\n * await this.auth.removeMfaDevice('sms');\n * ```\n */\n async removeMfaDevice(method: string): Promise<{ message: string }> {\n return this.client.removeMfaDevice(method);\n }\n\n /**\n * Set preferred MFA method.\n *\n * @param method - Device method to set as preferred ('totp', 'sms', 'email', or 'passkey')\n * @returns Promise with success message\n *\n * @example\n * ```typescript\n * await this.auth.setPreferredMfaMethod('totp');\n * ```\n */\n async setPreferredMfaMethod(method: 'totp' | 'sms' | 'email' | 'passkey'): Promise<{ message: string }> {\n return this.client.setPreferredMfaMethod(method);\n }\n\n /**\n * Generate backup codes.\n *\n * @returns Promise of backup codes array\n *\n * @example\n * ```typescript\n * const codes = await this.auth.generateBackupCodes();\n * console.log('Backup codes:', codes);\n * ```\n */\n async generateBackupCodes(): Promise<string[]> {\n return this.client.generateBackupCodes();\n }\n\n // ============================================================================\n // Device Trust\n // ============================================================================\n\n /**\n * Trust current device.\n *\n * @returns Promise with device token\n *\n * @example\n * ```typescript\n * const result = await this.auth.trustDevice();\n * console.log('Device trusted:', result.deviceToken);\n * ```\n */\n async trustDevice(): Promise<{ deviceToken: string }> {\n return this.client.trustDevice();\n }\n\n /**\n * Check if the current device is trusted.\n *\n * @returns Promise with trusted status\n *\n * @example\n * ```typescript\n * const result = await this.auth.isTrustedDevice();\n * if (result.trusted) {\n * console.log('This device is trusted');\n * }\n * ```\n */\n async isTrustedDevice(): Promise<{ trusted: boolean }> {\n return this.client.isTrustedDevice();\n }\n\n // ============================================================================\n // Audit History\n // ============================================================================\n\n /**\n * Get paginated audit history for the current user.\n *\n * @param params - Query parameters for filtering and pagination\n * @returns Promise of audit history response\n *\n * @example\n * ```typescript\n * const history = await this.auth.getAuditHistory({\n * page: 1,\n * limit: 20,\n * eventTypes: ['LOGIN_SUCCESS'],\n * eventStatus: ['FAILURE'],\n * });\n * console.log('Audit history:', history);\n * ```\n */\n async getAuditHistory(\n params?: Record<string, string | number | boolean | Array<string | number | boolean>>,\n ): Promise<AuditHistoryResponse> {\n return this.client.getAuditHistory(params);\n }\n\n // ============================================================================\n // Escape Hatch\n // ============================================================================\n\n /**\n * Expose underlying NAuthClient for advanced scenarios.\n *\n\n * @returns The underlying NAuthClient instance\n *\n * @example\n * ```typescript\n * // Deprecated - use direct methods instead\n * const status = await this.auth.getClient().getMfaStatus();\n *\n * // Preferred - use direct methods\n * const status = await this.auth.getMfaStatus();\n * ```\n */\n getClient(): NAuthClient {\n return this.client;\n }\n\n // ============================================================================\n // Admin Operations\n // ============================================================================\n\n /**\n * Admin operations (if enabled in config).\n *\n * Provides admin-level user management methods:\n * - User CRUD operations\n * - Password management\n * - Session management\n * - MFA management\n * - Audit history\n *\n * Returns undefined if admin was not configured.\n *\n * @returns AdminOperations instance or undefined\n *\n * @example\n * ```typescript\n * // Check if admin is available\n * if (this.auth.admin) {\n * const users = await this.auth.admin.getUsers({ page: 1 });\n * }\n *\n * // With optional chaining\n * await this.auth.admin?.deleteUser(sub);\n *\n * // Create user\n * const result = await this.auth.admin?.createUser({\n * email: 'user@example.com',\n * password: 'SecurePass123!',\n * isEmailVerified: true,\n * });\n * ```\n */\n get admin(): AdminOperations | undefined {\n return this.client.admin;\n }\n\n // ============================================================================\n // Internal Methods\n // ============================================================================\n\n /**\n * Initialize by hydrating state from storage.\n * Called automatically on construction.\n */\n private async initialize(): Promise<void> {\n if (this.initialized) return;\n this.initialized = true;\n\n await this.client.initialize();\n\n // Hydrate challenge state\n const storedChallenge = await this.client.getStoredChallenge();\n if (storedChallenge) {\n this.challengeSubject.next(storedChallenge);\n }\n\n // Update subjects from client state\n const user = this.client.getCurrentUser();\n if (user) {\n this.currentUserSubject.next(user);\n this.isAuthenticatedSubject.next(true);\n }\n }\n\n /**\n * Update challenge state after auth response.\n */\n private updateChallengeState(response: AuthResponse): AuthResponse {\n if (response.challengeName) {\n this.challengeSubject.next(response);\n } else {\n this.challengeSubject.next(null);\n }\n return response;\n }\n\n // ============================================================================\n // reCAPTCHA Helper\n // ============================================================================\n\n /**\n * Get reCAPTCHA token - auto-generate for v3 or use provided token.\n *\n * Handles platform detection:\n * - Web browser: Generate token if enabled and v3\n * - Capacitor native: Skip (use device attestation instead)\n * - SSR: Skip\n * - Manual mode (v2 or manualChallenge=true): Requires explicit token\n *\n * @param providedToken - Explicitly provided token (v2 manual mode)\n * @param action - Action name for v3 analytics\n * @returns reCAPTCHA token or undefined\n *\n * @private\n */\n private async getRecaptchaToken(providedToken: string | undefined, action: string): Promise<string | undefined> {\n // If token explicitly provided, use it (v2 manual mode)\n if (providedToken) {\n return providedToken;\n }\n\n // No reCAPTCHA service available\n if (!this.recaptchaService) {\n return undefined;\n }\n\n // Check if reCAPTCHA is configured\n const recaptchaConfig = (\n this.config as { recaptcha?: { enabled?: boolean; version?: string; manualChallenge?: boolean } }\n ).recaptcha;\n\n if (!recaptchaConfig?.enabled) {\n return undefined;\n }\n\n // Skip for platforms that don't support reCAPTCHA (SSR, Capacitor native)\n if (this.recaptchaService.shouldSkip()) {\n return undefined;\n }\n\n // v2 or manual mode - user must provide token explicitly\n if (recaptchaConfig.version === 'v2' || recaptchaConfig.manualChallenge) {\n return undefined;\n }\n\n // Auto-generate token for v3/Enterprise\n try {\n return await this.recaptchaService.execute(action);\n } catch (error: unknown) {\n // Log error but don't block authentication\n // Server will enforce if required\n console.warn('[AuthService] Failed to generate reCAPTCHA token:', error);\n return undefined;\n }\n }\n}\n","import { HttpClient, HttpErrorResponse, HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport {\n BehaviorSubject,\n Observable,\n catchError,\n finalize,\n from,\n map,\n of,\n shareReplay,\n switchMap,\n throwError,\n} from 'rxjs';\nimport type { NAuthClientConfig } from '@nauth-toolkit/client';\nimport { AuthService } from '../ngmodule/auth.service';\n\n/**\n * Shared interceptor logic for both:\n * - Functional interceptor (Angular 17+ standalone)\n * - Class-based interceptor (NgModule apps)\n *\n * WHY:\n * - Keep one implementation for cookies + json mode behavior.\n * - Avoid divergence between standalone and NgModule integrations.\n */\n\n// ============================================================================\n// Refresh state management (module-level)\n// ============================================================================\nlet isRefreshing = false;\nconst refreshTokenSubject = new BehaviorSubject<string | null>(null);\nlet refreshInFlight$: Observable<string> | null = null;\nconst retriedRequests = new WeakSet<HttpRequest<unknown>>();\n\n// ============================================================================\n// Error + cookie helpers\n// ============================================================================\n\n/**\n * Safely extract HTTP status code from either:\n * - Angular HttpErrorResponse (HttpClient calls)\n * - SDK NAuthClientError (thrown by the SDK's HttpAdapter)\n */\nfunction getStatusCode(error: unknown): number | null {\n if (error instanceof HttpErrorResponse) return error.status;\n if (typeof error === 'object' && error !== null && 'statusCode' in error) {\n const statusCode = (error as { statusCode?: unknown }).statusCode;\n return typeof statusCode === 'number' ? statusCode : null;\n }\n return null;\n}\n\n/**\n * Best-effort CSRF cookie clearing (non-httpOnly).\n *\n * WARNING: This cannot clear httpOnly auth cookies (access/refresh/device).\n * Those must be cleared by the backend on refresh/logout.\n */\nfunction clearCsrfCookie(baseUrl: string, cookieName: string): void {\n if (typeof document === 'undefined') return;\n\n // WHY: Cookie domain handling differs between localhost and real domains.\n // We try to clear with an explicit domain (if available), then without.\n try {\n const url = new URL(baseUrl);\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${url.hostname}`;\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n } catch {\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n }\n}\n\n/**\n * Get CSRF token from cookie.\n *\n * @param cookieName - Name of the CSRF cookie (from config.csrf.cookieName)\n * @returns CSRF token value or null if not found\n */\nfunction getCsrfToken(cookieName: string): string | null {\n if (typeof document === 'undefined') return null;\n // Escape special regex characters in cookie name to prevent injection\n const escapedCookieName = cookieName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const match = document.cookie.match(new RegExp(`(^| )${escapedCookieName}=([^;]+)`));\n return match ? decodeURIComponent(match[2]) : null;\n}\n\n/**\n * Build retry request with appropriate auth.\n *\n * In cookies mode: Browser automatically sends updated httpOnly cookies (access/refresh tokens).\n * We must re-read CSRF token after refresh to avoid stale headers.\n *\n * In JSON mode: Clones the request and adds the new Bearer token.\n */\nfunction buildRetryRequest(\n originalReq: HttpRequest<unknown>,\n tokenDelivery: string,\n newToken?: string | null,\n csrfConfig?: { cookieName?: string; headerName?: string },\n): HttpRequest<unknown> {\n if (tokenDelivery === 'json' && newToken && newToken !== 'success') {\n return originalReq.clone({ setHeaders: { Authorization: `Bearer ${newToken}` } });\n }\n\n if (tokenDelivery === 'cookies' && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(originalReq.method)) {\n const csrfCookieName = csrfConfig?.cookieName ?? 'nauth_csrf_token';\n const csrfHeaderName = csrfConfig?.headerName ?? 'x-csrf-token';\n // Always refresh CSRF token on retry (even if it exists, get fresh one)\n const freshCsrfToken = getCsrfToken(csrfCookieName);\n if (freshCsrfToken) {\n return originalReq.clone({ setHeaders: { [csrfHeaderName]: freshCsrfToken } });\n }\n }\n\n return originalReq;\n}\n\nexport function createNAuthAuthHttpInterceptor(params: {\n config: NAuthClientConfig;\n http: HttpClient;\n authService: AuthService;\n router: Router;\n next: HttpHandlerFn;\n req: HttpRequest<unknown>;\n}): Observable<HttpEvent<unknown>> {\n const { config, authService, router, next, req } = params;\n\n const tokenDelivery = config.tokenDelivery;\n const baseUrl = config.baseUrl;\n const endpoints = config.endpoints ?? {};\n const authPathPrefix = config.authPathPrefix;\n\n // Build refresh path with authPathPrefix if configured (matches core client buildUrl logic exactly)\n // Use default '/refresh' if endpoints.refresh is not defined\n const refreshPath = endpoints?.refresh ?? '/refresh';\n const normalizedRefreshPath = refreshPath.startsWith('/') ? refreshPath : `/${refreshPath}`;\n\n // Check if baseUrl already ends with authPathPrefix to avoid double-prefixing\n // This must match the core client's buildUrl logic exactly\n const baseUrlEndsWithPrefix = authPathPrefix && baseUrl.endsWith(authPathPrefix);\n\n const shouldAddPrefix = authPathPrefix && !baseUrlEndsWithPrefix && !normalizedRefreshPath.startsWith(authPathPrefix);\n const effectiveRefreshPath = shouldAddPrefix ? `${authPathPrefix}${normalizedRefreshPath}` : normalizedRefreshPath;\n\n const loginPath = endpoints.login ?? '/login';\n const signupPath = endpoints.signup ?? '/signup';\n const socialExchangePath = endpoints.socialExchange ?? '/social/exchange';\n\n const isAuthApiRequest = req.url.includes(baseUrl);\n // Check if request is to refresh endpoint (using effective path with authPathPrefix)\n const isRefreshEndpoint = req.url.includes(effectiveRefreshPath);\n const isPublicEndpoint =\n req.url.includes(loginPath) || req.url.includes(signupPath) || req.url.includes(socialExchangePath);\n const shouldIntercept = isAuthApiRequest && !isRefreshEndpoint && !isPublicEndpoint;\n\n // ============================================================================\n // Build request for cookies mode (withCredentials + CSRF)\n // ============================================================================\n // IMPORTANT: When using AngularHttpAdapter, headers from buildHeaders() are passed\n // to HttpClient.request() as a plain object. Angular converts these to HttpHeaders\n // and creates an HttpRequest. However, we cannot rely on buildHeaders() to add CSRF\n // in Angular context because:\n // 1. hasWindow() might return false in SSR contexts\n // 2. Headers might not be properly merged into the HttpRequest that interceptors receive\n // 3. The interceptor is the authoritative place for CSRF in Angular apps\n //\n // Therefore, the interceptor ALWAYS adds CSRF for mutating methods in cookies mode,\n // regardless of whether buildHeaders() added it (for vanilla clients).\n let authReq = req;\n if (tokenDelivery === 'cookies') {\n authReq = authReq.clone({ withCredentials: true });\n // Add CSRF token for mutating methods (POST, PUT, PATCH, DELETE)\n // Always add it here - don't rely on buildHeaders() in Angular context\n // Add CSRF token for mutating methods (POST, PUT, PATCH, DELETE)\n // This runs for ALL requests in cookies mode, not just auth API requests\n // This ensures CSRF protection for all mutating operations\n if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)) {\n // Respect user's CSRF config, fallback to defaults if not provided\n // These defaults must match the backend's CSRF configuration\n const csrfCookieName = config.csrf?.cookieName ?? 'nauth_csrf_token';\n const csrfHeaderName = config.csrf?.headerName ?? 'x-csrf-token';\n\n // Get CSRF token from cookie using the configured cookie name\n const csrfToken = getCsrfToken(csrfCookieName);\n\n if (csrfToken) {\n // Use setHeaders which will override if already exists (from buildHeaders)\n // This ensures CSRF is always present for DELETE and other mutating methods\n authReq = authReq.clone({ setHeaders: { [csrfHeaderName]: csrfToken } });\n } else {\n // CSRF token not found - this could happen if:\n // 1. Cookie doesn't exist (before first login, after logout, or cookie expired)\n // 2. Cookie name mismatch (check config.csrf.cookieName matches backend)\n // 3. Cookie is httpOnly and can't be read (but CSRF cookies should be readable)\n // The backend should handle missing CSRF tokens appropriately (return 403 or similar)\n }\n }\n }\n\n // ============================================================================\n // JSON mode: attach Authorization header for HttpClient calls\n // ============================================================================\n // Simple approach: attach token if available, let backend validate\n // Handle 401 reactively (matches old working implementation)\n const attachJsonAuth$ =\n tokenDelivery === 'json' && shouldIntercept && !authReq.headers.has('Authorization')\n ? from(authService.getAccessToken()).pipe(\n switchMap((token) => {\n if (token) {\n return of(authReq.clone({ setHeaders: { Authorization: `Bearer ${token}` } }));\n }\n return of(authReq);\n }),\n )\n : of(authReq);\n\n // ============================================================================\n // Refresh coordination\n // ============================================================================\n const getOrStartRefresh$ = (): Observable<string> => {\n if (refreshInFlight$) return refreshInFlight$;\n\n // WHY: We want to ensure only one refresh request is in flight at any time.\n // All requests (including those that haven't hit the backend yet) should wait for\n // the same refresh result to avoid a burst of 401s and potential WAF/rate-limit issues.\n isRefreshing = true;\n refreshTokenSubject.next(null);\n\n // WHY: Always refresh via the core client.\n // - Ensures authPathPrefix + default endpoints are applied consistently (fixes /refresh vs /auth/refresh).\n // - Centralizes CSRF + credentials handling in one place.\n const refreshRequest$ = from(authService.getClient().refreshTokens());\n\n refreshInFlight$ = refreshRequest$.pipe(\n map((response) => {\n // Cookies mode: success is enough (tokens are in httpOnly cookies).\n // JSON mode: we need the new access token to retry + unblock queued requests.\n const newToken = tokenDelivery === 'json' ? response.accessToken : 'success';\n\n if (tokenDelivery === 'json' && (!newToken || newToken === 'success')) {\n // ⚠️ WARNING: Without an access token we cannot safely retry requests in JSON mode.\n throw new Error('Token refresh did not return an access token');\n }\n\n refreshTokenSubject.next(newToken ?? 'success');\n return newToken ?? 'success';\n }),\n catchError((err) => {\n refreshTokenSubject.next(null);\n\n const statusCode = getStatusCode(err);\n\n // Refresh failed with 401 => session expired.\n // Clear *local* SDK state so guards/pages don't think the user is still logged in after navigation/reload.\n // IMPORTANT: This also clears challenge sessions and OAuth state to prevent ghost states.\n if (statusCode === 401) {\n // Best-effort: also clear CSRF cookie in cookies mode (non-httpOnly).\n if (tokenDelivery === 'cookies') {\n const csrfCookieName = config.csrf?.cookieName ?? 'nauth_csrf_token';\n clearCsrfCookie(config.baseUrl, csrfCookieName);\n }\n\n return from(authService.getClient().clearLocalAuthState()).pipe(\n switchMap(() => {\n // Call onSessionExpired callback if configured\n config.onSessionExpired?.();\n\n if (config.redirects?.sessionExpired) {\n router.navigateByUrl(config.redirects.sessionExpired).catch(() => {\n // Ignore navigation errors\n });\n }\n return throwError(() => err);\n }),\n );\n }\n\n return throwError(() => err);\n }),\n finalize(() => {\n isRefreshing = false;\n refreshInFlight$ = null;\n }),\n shareReplay({ bufferSize: 1, refCount: false }),\n );\n\n return refreshInFlight$;\n };\n\n // ============================================================================\n // Pre-request gating: block requests while refresh is in-flight\n // ============================================================================\n // WHY: Prevent multiple requests from hitting the backend with an expired token and returning 401.\n // We queue all auth API calls during refresh and release them once refresh succeeds.\n if (shouldIntercept && isRefreshing && refreshInFlight$) {\n return refreshInFlight$.pipe(\n switchMap((token) => {\n const gatedReq = buildRetryRequest(authReq, tokenDelivery, token, config.csrf);\n return next(gatedReq);\n }),\n );\n }\n\n return attachJsonAuth$.pipe(\n switchMap((requestWithAuth) =>\n next(requestWithAuth).pipe(\n catchError((error: unknown) => {\n const shouldHandle =\n error instanceof HttpErrorResponse && error.status === 401 && shouldIntercept && !retriedRequests.has(req);\n\n if (!shouldHandle) {\n return throwError(() => error);\n }\n\n retriedRequests.add(req);\n\n return getOrStartRefresh$().pipe(\n switchMap((token) => {\n const retryReq = buildRetryRequest(requestWithAuth, tokenDelivery, token, config.csrf);\n retriedRequests.add(retryReq);\n return next(retryReq);\n }),\n );\n }),\n ),\n ),\n );\n}\n","import { Injectable, Inject } from '@angular/core';\nimport { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpClient } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { Observable } from 'rxjs';\nimport { NAUTH_CLIENT_CONFIG } from './tokens';\nimport { AuthService } from './auth.service';\nimport { NAuthClientConfig } from '@nauth-toolkit/client';\nimport { createNAuthAuthHttpInterceptor } from '../lib/auth-interceptor.shared';\n\n/**\n * Class-based HTTP interceptor for NgModule apps (Angular < 17).\n *\n * For standalone components (Angular 17+), use the functional `authInterceptor` instead.\n *\n * @example\n * ```typescript\n * // app.module.ts\n * import { HTTP_INTERCEPTORS } from '@angular/common/http';\n * import { AuthInterceptorClass } from '@nauth-toolkit/client-angular';\n *\n * @NgModule({\n * providers: [\n * { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptorClass, multi: true }\n * ]\n * })\n * ```\n */\n@Injectable()\nexport class AuthInterceptorClass implements HttpInterceptor {\n constructor(\n @Inject(NAUTH_CLIENT_CONFIG) private readonly config: NAuthClientConfig,\n private readonly http: HttpClient,\n private readonly authService: AuthService,\n private readonly router: Router,\n ) {}\n\n intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\n return createNAuthAuthHttpInterceptor({\n config: this.config,\n http: this.http,\n authService: this.authService,\n router: this.router,\n req,\n next: (r) => next.handle(r),\n });\n }\n}\n","import { inject, Inject, Injectable, Optional } from '@angular/core';\nimport { CanActivateFn, Router, UrlTree } from '@angular/router';\nimport { AuthService } from '../ngmodule/auth.service';\nimport { NAUTH_CLIENT_CONFIG } from '../ngmodule/tokens';\nimport type { NAuthClientConfig } from '@nauth-toolkit/client';\n\n/**\n * Functional route guard for authentication (Angular 17+).\n *\n * Protects routes by checking if user is authenticated.\n * Redirects to configured session expired route (or login) if not authenticated.\n *\n * @param redirectTo - Optional path to redirect to if not authenticated. If not provided, uses `redirects.sessionExpired` from config (defaults to '/login')\n * @returns CanActivateFn guard function\n *\n * @example\n * ```typescript\n * // In route configuration - uses config.redirects.sessionExpired\n * const routes: Routes = [\n * {\n * path: 'home',\n * component: HomeComponent,\n * canActivate: [authGuard()]\n * }\n * ];\n *\n * // Override with custom route\n * const routes: Routes = [\n * {\n * path: 'admin',\n * component: AdminComponent,\n * canActivate: [authGuard('/admin/login')]\n * }\n * ];\n * ```\n */\nexport function authGuard(redirectTo?: string): CanActivateFn {\n return (): boolean | UrlTree => {\n const auth = inject(AuthService);\n const router = inject(Router);\n const config = inject(NAUTH_CLIENT_CONFIG, { optional: true });\n\n if (auth.isAuthenticated()) {\n return true;\n }\n\n // Use provided redirectTo, or config.redirects.sessionExpired, or default to '/login'\n const redirectPath = redirectTo ?? config?.redirects?.sessionExpired ?? '/login';\n\n return router.createUrlTree([redirectPath]);\n };\n}\n\n/**\n * Class-based authentication guard for NgModule compatibility.\n *\n * **Note:** When using `NAuthModule.forRoot()`, `AuthGuard` is automatically provided\n * and has access to the configuration. You don't need to add it to your module's providers.\n *\n * @example\n * ```typescript\n * // app.module.ts - AuthGuard is automatically provided by NAuthModule.forRoot()\n * @NgModule({\n * imports: [\n * NAuthModule.forRoot({\n * baseUrl: 'https://api.example.com/auth',\n * tokenDelivery: 'cookies',\n * redirects: {\n * sessionExpired: '/login?expired=true',\n * },\n * }),\n * RouterModule.forRoot([\n * {\n * path: 'home',\n * component: HomeComponent,\n * canActivate: [AuthGuard], // Uses config.redirects.sessionExpired\n * },\n * ]),\n * ],\n * })\n * export class AppModule {}\n *\n * // Or provide manually in a feature module (still has access to root config)\n * @NgModule({\n * providers: [AuthGuard],\n * })\n * export class FeatureModule {}\n * ```\n */\n@Injectable()\nexport class AuthGuard {\n /**\n * @param auth - Authentication service\n * @param router - Angular router\n * @param config - Optional client configuration (injected automatically)\n */\n constructor(\n private auth: AuthService,\n private router: Router,\n @Optional() @Inject(NAUTH_CLIENT_CONFIG) private config?: NAuthClientConfig,\n ) {}\n\n /**\n * Check if route can be activated.\n *\n * @returns True if authenticated, otherwise redirects to configured session expired route (or '/login')\n */\n canActivate(): boolean | UrlTree {\n if (this.auth.isAuthenticated()) {\n return true;\n }\n\n // Use config.redirects.sessionExpired or default to '/login'\n const redirectPath = this.config?.redirects?.sessionExpired ?? '/login';\n\n return this.router.createUrlTree([redirectPath]);\n }\n}\n","import { NgModule, ModuleWithProviders, inject, Optional, APP_INITIALIZER } from '@angular/core';\nimport { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { NAUTH_CLIENT_CONFIG, NAuthAngularConfig } from './tokens';\nimport { AuthService } from './auth.service';\nimport { AngularHttpAdapter } from './http-adapter';\nimport { AuthInterceptorClass } from './auth.interceptor.class';\nimport { AuthGuard } from '../lib/auth.guard';\nimport { RecaptchaService, RECAPTCHA_CONFIG } from '../lib/recaptcha.service';\n\n/**\n * NgModule for nauth-toolkit Angular integration.\n *\n * Use this for NgModule-based apps (Angular 17+ with NgModule or legacy apps).\n *\n * @example Basic Setup\n * ```typescript\n * // app.module.ts\n * import { NAuthModule } from '@nauth-toolkit/client-angular';\n *\n * @NgModule({\n * imports: [\n * NAuthModule.forRoot({\n * baseUrl: 'http://localhost:3000/auth',\n * tokenDelivery: 'cookies',\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n *\n * @example With reCAPTCHA Enterprise\n * ```typescript\n * NAuthModule.forRoot({\n * baseUrl: 'http://localhost:3000/auth',\n * tokenDelivery: 'cookies',\n * recaptcha: {\n * enabled: true,\n * version: 'enterprise',\n * siteKey: environment.recaptchaSiteKey,\n * action: 'login',\n * },\n * })\n * ```\n */\n@NgModule({\n imports: [HttpClientModule],\n exports: [HttpClientModule],\n})\nexport class NAuthModule {\n static forRoot(config: NAuthAngularConfig): ModuleWithProviders<NAuthModule> {\n const providers: any[] = [\n {\n provide: NAUTH_CLIENT_CONFIG,\n useValue: config,\n },\n AngularHttpAdapter,\n {\n provide: AuthService,\n useFactory: (httpAdapter: AngularHttpAdapter, recaptchaService?: RecaptchaService) => {\n // Try to inject Router optionally - if not available, pass undefined\n // Router will be undefined if not provided (e.g., in apps without routing)\n const router = inject(Router, { optional: true });\n return new AuthService(config, httpAdapter, router ?? undefined, recaptchaService);\n },\n deps: [AngularHttpAdapter, [new Optional(), RecaptchaService]],\n },\n {\n provide: HTTP_INTERCEPTORS,\n useClass: AuthInterceptorClass,\n multi: true,\n },\n // Provide AuthGuard so it has access to NAUTH_CLIENT_CONFIG\n AuthGuard,\n ];\n\n // Add reCAPTCHA providers if configured\n if (config.recaptcha?.enabled) {\n providers.push(\n {\n provide: RECAPTCHA_CONFIG,\n // Cast because interface extends but they're compatible\n useValue: config.recaptcha,\n },\n RecaptchaService,\n {\n provide: APP_INITIALIZER,\n useFactory: () => {\n // Force RecaptchaService instantiation at app startup so script preloads\n inject(RecaptchaService);\n // No-op - constructor already handles preload\n return () => {};\n },\n multi: true,\n },\n );\n }\n\n return {\n ngModule: NAuthModule,\n providers,\n };\n }\n}\n","import { inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { HttpHandlerFn, HttpInterceptorFn, HttpRequest, HttpClient } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { NAUTH_CLIENT_CONFIG } from '../ngmodule/tokens';\nimport { AuthService } from '../ngmodule/auth.service';\nimport { createNAuthAuthHttpInterceptor } from './auth-interceptor.shared';\n\n/**\n * Angular HTTP interceptor for nauth-toolkit.\n *\n * Handles:\n * - Cookies mode: withCredentials + CSRF tokens + refresh via POST\n * - JSON mode: refresh via SDK, retry with new token\n */\nexport const authInterceptor: HttpInterceptorFn = (req: HttpRequest<unknown>, next: HttpHandlerFn) => {\n const config = inject(NAUTH_CLIENT_CONFIG);\n const http = inject(HttpClient);\n const authService = inject(AuthService);\n const platformId = inject(PLATFORM_ID);\n const router = inject(Router);\n const isBrowser = isPlatformBrowser(platformId);\n\n if (!isBrowser) {\n return next(req);\n }\n\n return createNAuthAuthHttpInterceptor({ config, http, authService, router, next, req });\n};\n\n/**\n * Class-based interceptor for NgModule compatibility.\n */\nexport class AuthInterceptor {\n intercept(req: HttpRequest<unknown>, next: HttpHandlerFn) {\n return authInterceptor(req, next);\n }\n}\n","import { inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { type CanActivateFn } from '@angular/router';\nimport { AuthService } from '../ngmodule/auth.service';\nimport { NAuthClientError, NAuthErrorCode, type AuthResponse } from '@nauth-toolkit/client';\n\n/**\n * Social redirect callback route guard.\n *\n * This guard supports the redirect-first social flow where the backend redirects\n * back to the frontend with:\n * - `appState` (always optional)\n * - `exchangeToken` (present for json/hybrid flows, and for cookie flows that return a challenge)\n * - `error` / `error_description` (provider errors)\n *\n * Behavior:\n * - If `exchangeToken` exists: exchanges it via backend (SDK handles navigation automatically).\n * - If no `exchangeToken`: treat as cookie-success path (SDK handles navigation automatically).\n * - If `error` exists: redirects to oauthError route.\n * - If auto-redirect is disabled (redirectUrls set to null): returns true to activate the route.\n *\n * @example\n * ```typescript\n * import { socialRedirectCallbackGuard } from '@nauth-toolkit/client/angular';\n *\n * export const routes: Routes = [\n * { path: 'auth/callback', canActivate: [socialRedirectCallbackGuard], component: CallbackComponent },\n * ];\n * ```\n */\nexport const socialRedirectCallbackGuard: CanActivateFn = async (): Promise<boolean> => {\n const auth = inject(AuthService);\n const platformId = inject(PLATFORM_ID);\n const isBrowser = isPlatformBrowser(platformId);\n\n if (!isBrowser) {\n return false;\n }\n\n const params = new URLSearchParams(window.location.search);\n const error = params.get('error');\n const exchangeToken = params.get('exchangeToken');\n const appState = params.get('appState');\n\n const router = auth.getChallengeRouter();\n\n // ============================================================================\n // Extract and store appState if present\n // ============================================================================\n // WHY: appState is round-tripped from the OAuth flow and should be stored\n // for retrieval via getLastOauthState() and passed to the success route.\n if (appState) {\n await auth.getClient().storeOauthState(appState);\n }\n\n // Provider error: redirect to oauthError (or activate route if auto-redirect disabled)\n if (error) {\n await router.navigateToError('oauth');\n // Return true to activate route if oauthError redirect is disabled\n return router.isErrorRedirectDisabled('oauth');\n }\n\n // No exchangeToken: cookie success path; hydrate then navigate to success.\n //\n // Note: When auto-redirect is enabled, we do not \"activate\" the callback route to avoid\n // consumers needing to render a page. When disabled, we activate the route.\n if (!exchangeToken) {\n // ============================================================================\n // Cookies mode: hydrate user state before redirecting\n // ============================================================================\n // WHY: In cookie delivery, the OAuth callback completes via browser redirects, so the frontend\n // does not receive a JSON AuthResponse to populate the SDK's cached `currentUser`.\n //\n // Without this, sync guards (`authGuard`) can immediately redirect to /login because\n // `currentUser` is still null even though cookies were set successfully.\n try {\n const user = await auth.getProfile();\n\n // ============================================================================\n // Route through handleAuthResponse to ensure onAuthResponse is called\n // ============================================================================\n // WHY: onAuthResponse should be called consistently for all auth completions,\n // whether via exchange token or cookie success path. This allows apps to have\n // a single handler for all authentication outcomes (login, signup, social).\n //\n // We construct a synthetic AuthResponse with the user data. Tokens are omitted\n // because they're in httpOnly cookies, not accessible to the client.\n const syntheticResponse: AuthResponse = {\n user: {\n sub: user.sub,\n email: user.email,\n firstName: user.firstName,\n lastName: user.lastName,\n phone: user.phone,\n isEmailVerified: user.isEmailVerified,\n isPhoneVerified: user.isPhoneVerified,\n socialProviders: user.socialProviders,\n hasPasswordHash: user.hasPasswordHash,\n },\n authMethod: user.sessionAuthMethod ?? undefined,\n };\n\n // Call handleAuthResponse which respects onAuthResponse callback\n // Pass appState in context so onAuthResponse can access it\n await router.handleAuthResponse(syntheticResponse, {\n source: 'social',\n appState: appState ?? undefined,\n });\n } catch (error: unknown) {\n // Only treat auth failures (401/403) as OAuth errors\n // Network errors or other issues might be temporary - still try success route\n\n // Type guard: check if error is NAuthClientError\n if (error instanceof NAuthClientError) {\n const isAuthError =\n error.statusCode === 401 ||\n error.statusCode === 403 ||\n error.code === NAuthErrorCode.AUTH_TOKEN_INVALID ||\n error.code === NAuthErrorCode.AUTH_SESSION_EXPIRED ||\n error.code === NAuthErrorCode.AUTH_SESSION_NOT_FOUND;\n\n if (isAuthError) {\n // Cookies weren't set properly - OAuth failed\n await router.navigateToError('oauth');\n return router.isErrorRedirectDisabled('oauth');\n }\n }\n\n // For network errors or other non-auth issues, proceed to success route\n // The auth guard will handle authentication state on the next route\n await router.navigateToSuccess(appState ? { appState } : undefined);\n }\n\n // Return true if success redirect is disabled, allowing the callback component to render\n return router.isSuccessRedirectDisabled({ source: 'social', appState: appState ?? undefined });\n }\n\n // Exchange token - SDK handles navigation automatically\n // Note: appState will be passed via query params when navigateToSuccess is called\n // by the challenge router after successful exchange\n await auth.exchangeSocialRedirect(exchangeToken);\n\n // Return true if success redirect is disabled, allowing the callback component to render\n // We use 'social' as source since this is the social OAuth callback flow\n return router.isSuccessRedirectDisabled({ source: 'social', appState: appState ?? undefined });\n};\n","import { inject, EnvironmentProviders, makeEnvironmentProviders, APP_INITIALIZER } from '@angular/core';\nimport { RecaptchaService, RECAPTCHA_CONFIG, RecaptchaServiceConfig } from './recaptcha.service';\nimport { NAUTH_CLIENT_CONFIG } from '../ngmodule/tokens';\n\n/**\n * Provides reCAPTCHA configuration and automatic script preloading.\n *\n * **IMPORTANT:** When using with `NAUTH_CLIENT_CONFIG`, you must pass\n * `provideRecaptcha()` call MUST appear AFTER the `NAUTH_CLIENT_CONFIG` provider.\n *\n * Sets up `RECAPTCHA_CONFIG` and `RecaptchaService`. When called without config,\n * reads from `NAUTH_CLIENT_CONFIG.recaptcha` if available.\n *\n * @param config - Optional. reCAPTCHA config (enabled, version, siteKey, action).\n * If omitted, will attempt to use `NAUTH_CLIENT_CONFIG.recaptcha`.\n * Pass explicitly when not using NAuth or to override.\n * @returns Environment providers for reCAPTCHA\n *\n * @example With NAUTH_CLIENT_CONFIG (no duplication)\n * ```typescript\n * providers: [\n * { provide: NAUTH_CLIENT_CONFIG, useValue: { baseUrl: '...', recaptcha: { enabled: true, version: 'enterprise', siteKey: '...', action: 'login' } } },\n * provideRecaptcha(), // reads NAUTH_CLIENT_CONFIG.recaptcha at runtime\n * ]\n * ```\n *\n * @example Without NAuth (explicit config)\n * ```typescript\n * provideRecaptcha({ enabled: true, version: 'v3', siteKey: '...', action: 'login' })\n * ```\n */\nexport function provideRecaptcha(config?: RecaptchaServiceConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: RECAPTCHA_CONFIG,\n useFactory: (): RecaptchaServiceConfig | undefined => {\n if (config !== undefined) {\n return config;\n }\n // Try to inject NAUTH_CLIENT_CONFIG at runtime\n try {\n const clientConfig = inject(NAUTH_CLIENT_CONFIG, { optional: true });\n const recaptchaConfig = clientConfig?.recaptcha;\n\n // Debug log when debug is enabled\n if (typeof console !== 'undefined' && clientConfig?.debug && recaptchaConfig) {\n console.log('[provideRecaptcha] Using NAUTH_CLIENT_CONFIG.recaptcha');\n }\n\n return recaptchaConfig as RecaptchaServiceConfig | undefined;\n } catch {\n // Injection failed (NAUTH_CLIENT_CONFIG not available)\n return undefined;\n }\n },\n },\n RecaptchaService,\n {\n provide: APP_INITIALIZER,\n useFactory: () => {\n return () => {\n const c = inject(RECAPTCHA_CONFIG);\n if (c?.enabled && (c.version === 'v3' || c.version === 'enterprise')) {\n inject(RecaptchaService)\n .loadScript()\n .catch(() => {});\n }\n };\n },\n multi: true,\n },\n ]);\n}\n","/**\n * Public API Surface of @nauth-toolkit/client-angular (NgModule)\n *\n * This is the default entry point for NgModule-based Angular apps.\n * For standalone components, use: @nauth-toolkit/client-angular/standalone\n */\n\n// Re-export core client types and utilities\nexport * from '@nauth-toolkit/client';\n\n// Export NgModule-specific components (class-based)\nexport * from './ngmodule/tokens';\nexport * from './ngmodule/auth.service';\nexport * from './ngmodule/http-adapter';\nexport * from './ngmodule/auth.interceptor.class';\nexport * from './ngmodule/nauth.module';\n\n// Export functional components (for flexibility in NgModule apps too)\nexport * from './lib/auth.interceptor';\nexport * from './lib/auth.guard';\nexport * from './lib/social-redirect-callback.guard';\nexport * from './lib/recaptcha.service';\nexport * from './lib/recaptcha-provider';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.AngularHttpAdapter","i3.RecaptchaService","i2.AuthService","i3"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nauth-toolkit/client-angular",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.102",
|
|
4
4
|
"description": "Angular adapter for nauth-toolkit client SDK",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nauth",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"@angular/common": ">=17.0.0",
|
|
26
26
|
"@angular/core": ">=17.0.0",
|
|
27
|
-
"@nauth-toolkit/client": "^0.1.
|
|
27
|
+
"@nauth-toolkit/client": "^0.1.102",
|
|
28
28
|
"rxjs": "^7.0.0 || ^8.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|