import { __awaiter } from 'tslib';
import * as i0 from '@angular/core';
import { Component, Inject, Input, NgModule } from '@angular/core';
import { FormControl } from '@angular/forms';
import * as i1 from '@aztrix/sdk';
import { BASE_URL } from '@aztrix/sdk';
import { combineLatest, map, from } from 'rxjs';
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i3 from '@aztrix/components/button';
import { ButtonModule } from '@aztrix/components/button';
import * as i4 from '@aztrix/components/value-edit';
import { ValueEditModule } from '@aztrix/components/value-edit';
import * as i5 from '@aztrix/helpers';
import { HelperPipesModule } from '@aztrix/helpers';

class WebIdProvidersComponent {
    constructor(_solid, _baseUrl) {
        this._solid = _solid;
        this._baseUrl = _baseUrl;
        this.label = 'settings.web-id.link-to-account';
        this.urlForm = new FormControl();
        this.defaultProvider = { name: 'use.id Sandbox', url: 'https://sandbox.idp.use.id' };
        this.mode = 'choose';
        this.providers = [
            this.defaultProvider,
            { name: 'Solid Web', url: 'https://solidweb.me' },
            { name: 'Solid Community', url: 'https://solidcommunity.net' },
            { name: 'Inrupt', url: 'https://login.inrupt.com/' },
        ];
    }
    showProviders() {
        this.mode = 'providers';
    }
    initiate(webIdUrl, identityProviderUrl) {
        if (!webIdUrl && !identityProviderUrl) {
            identityProviderUrl = this.defaultProvider.url;
        }
        const codeVerifier = this._generateCodeVerifier();
        sessionStorage.setItem('aztrix:web-id:code_verifier', codeVerifier);
        if (webIdUrl) {
            sessionStorage.setItem('aztrix:web-id:url', webIdUrl);
        }
        else {
            sessionStorage.removeItem('aztrix:web-id:url');
        }
        if (identityProviderUrl) {
            sessionStorage.setItem('aztrix:web-id:identity_provider_url', identityProviderUrl);
        }
        else {
            sessionStorage.removeItem('aztrix:web-id:identity_provider_url');
        }
        combineLatest([
            this._generateChallengeFromCodeVerifier$(codeVerifier),
            this._solid
                .getAuthorizationUrl(webIdUrl, identityProviderUrl, 'response')
                .pipe(map((response) => response.headers.get('location'))),
        ]).subscribe(([codeChallenge, redirectUrl]) => {
            const url = new URL(redirectUrl);
            url.searchParams.set('code_challenge', codeChallenge);
            url.searchParams.set('redirect_uri', `${this._baseUrl}/web-id/callback`);
            window.location.assign(url.toString());
        });
    }
    _generateCodeVerifier() {
        const array = new Uint32Array(14);
        window.crypto.getRandomValues(array);
        return Array.from(array, (v) => {
            const decString = '0' + v.toString(16);
            return decString.substring(0, decString.length - 2);
        }).join('');
    }
    _generateChallengeFromCodeVerifier$(codeVerifier) {
        return from(this._generateChallengeFromCodeVerifier(codeVerifier));
    }
    _generateChallengeFromCodeVerifier(codeVerifier) {
        return __awaiter(this, void 0, void 0, function* () {
            const encoder = new TextEncoder();
            const data = encoder.encode(codeVerifier);
            const hashed = yield window.crypto.subtle.digest('SHA-256', data);
            let str = '';
            const bytes = new Uint8Array(hashed);
            const length = bytes.byteLength;
            for (let i = 0; i < length; i++) {
                str += String.fromCharCode(bytes[i]);
            }
            return btoa(str).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
        });
    }
}
WebIdProvidersComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: WebIdProvidersComponent, deps: [{ token: i1.SolidService }, { token: BASE_URL }], target: i0.ɵɵFactoryTarget.Component });
WebIdProvidersComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.5", type: WebIdProvidersComponent, selector: "ax-web-id-providers", inputs: { label: "label" }, ngImport: i0, template: "<div class=\"content\" *ngIf=\"mode === 'choose'\">\n  <button axButton color=\"primary\" filled (click)=\"showProviders()\">\n    {{ label | translate }}\n  </button>\n  <span class=\"or\">{{ 'label.or' | translate }}</span>\n  <button axButton filled color=\"primary\" (click)=\"initiate()\">\n    {{ 'settings.web-id.create-new' | translate }}\n  </button>\n</div>\n\n<div class=\"content\" *ngIf=\"mode === 'providers'\">\n  <p>{{ 'settings.web-id.providers.select' | translate }}</p>\n\n  <div class=\"providers\">\n    <button\n      *ngFor=\"let provider of providers\"\n      axButton\n      color=\"primary\"\n      filled\n      (click)=\"initiate(undefined, provider.url)\"\n    >\n      {{ provider.name }}\n    </button>\n  </div>\n\n  <span class=\"or\">{{ 'label.or' | translate }}</span>\n\n  <div class=\"custom\">\n    <ax-value-edit\n      type=\"URL\"\n      [label]=\"'settings.web-id.input.label' | translate\"\n      [form]=\"urlForm\"\n    ></ax-value-edit>\n    <button axButton filled color=\"primary\" (click)=\"initiate(urlForm.value)\">\n      {{ 'label.go' | translate }}\n    </button>\n  </div>\n</div>\n", styles: [":host{display:block;z-index:1;position:relative;padding:1rem;margin:1rem 0 100px}@media screen and (min-width: 400px){:host{margin:1rem auto 100px}}@media only screen and (min-width: 600px){:host{margin:50px auto 100px}}.content{display:flex;flex-direction:column}.or{font-size:1rem;font-weight:700;text-transform:uppercase;text-align:center;margin:1rem}.custom{display:grid;align-items:center;justify-content:space-between;grid-template-columns:1fr auto;gap:1rem}.providers{display:flex;flex-direction:column;gap:1rem}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ButtonDirective, selector: "[axButton]", inputs: ["color", "labelHideMobile", "smallButton", "bigButton", "fullWidth", "filled", "outline", "icon-button", "hoverLabel", "hover", "lowercase", "disabled"] }, { kind: "component", type: i4.ValueEditComponent, selector: "ax-value-edit", inputs: ["type", "numberConfig"] }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: WebIdProvidersComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ax-web-id-providers', template: "<div class=\"content\" *ngIf=\"mode === 'choose'\">\n  <button axButton color=\"primary\" filled (click)=\"showProviders()\">\n    {{ label | translate }}\n  </button>\n  <span class=\"or\">{{ 'label.or' | translate }}</span>\n  <button axButton filled color=\"primary\" (click)=\"initiate()\">\n    {{ 'settings.web-id.create-new' | translate }}\n  </button>\n</div>\n\n<div class=\"content\" *ngIf=\"mode === 'providers'\">\n  <p>{{ 'settings.web-id.providers.select' | translate }}</p>\n\n  <div class=\"providers\">\n    <button\n      *ngFor=\"let provider of providers\"\n      axButton\n      color=\"primary\"\n      filled\n      (click)=\"initiate(undefined, provider.url)\"\n    >\n      {{ provider.name }}\n    </button>\n  </div>\n\n  <span class=\"or\">{{ 'label.or' | translate }}</span>\n\n  <div class=\"custom\">\n    <ax-value-edit\n      type=\"URL\"\n      [label]=\"'settings.web-id.input.label' | translate\"\n      [form]=\"urlForm\"\n    ></ax-value-edit>\n    <button axButton filled color=\"primary\" (click)=\"initiate(urlForm.value)\">\n      {{ 'label.go' | translate }}\n    </button>\n  </div>\n</div>\n", styles: [":host{display:block;z-index:1;position:relative;padding:1rem;margin:1rem 0 100px}@media screen and (min-width: 400px){:host{margin:1rem auto 100px}}@media only screen and (min-width: 600px){:host{margin:50px auto 100px}}.content{display:flex;flex-direction:column}.or{font-size:1rem;font-weight:700;text-transform:uppercase;text-align:center;margin:1rem}.custom{display:grid;align-items:center;justify-content:space-between;grid-template-columns:1fr auto;gap:1rem}.providers{display:flex;flex-direction:column;gap:1rem}\n"] }]
        }], ctorParameters: function () {
        return [{ type: i1.SolidService }, { type: undefined, decorators: [{
                        type: Inject,
                        args: [BASE_URL]
                    }] }];
    }, propDecorators: { label: [{
                type: Input
            }] } });

class WebIdProvidersModule {
}
WebIdProvidersModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: WebIdProvidersModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
WebIdProvidersModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.5", ngImport: i0, type: WebIdProvidersModule, declarations: [WebIdProvidersComponent], imports: [CommonModule, ButtonModule, HelperPipesModule, ValueEditModule], exports: [WebIdProvidersComponent] });
WebIdProvidersModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: WebIdProvidersModule, imports: [CommonModule, ButtonModule, HelperPipesModule, ValueEditModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: WebIdProvidersModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [WebIdProvidersComponent],
                    imports: [CommonModule, ButtonModule, HelperPipesModule, ValueEditModule],
                    exports: [WebIdProvidersComponent],
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { WebIdProvidersComponent, WebIdProvidersModule };
//# sourceMappingURL=aztrix-components-web-id-providers.mjs.map
//# sourceMappingURL=aztrix-components-web-id-providers.mjs.map
