var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { DwnErrorCode } from '../../src/core/dwn-error.js';
import { expect } from 'chai';
import { TestDataGenerator } from '../utils/test-data-generator.js';
import { authenticate, validateAuthorizationIntegrity } from '../../src/core/auth.js';
import { DidResolver, RecordsRead } from '../../src/index.js';
import { Did } from '../../src/did/did.js';
import { DidIonResolver } from '../../src/did/did-ion-resolver.js';
import { DidKeyResolver } from '../../src/did/did-key-resolver.js';
import { GeneralJwsSigner } from '../../src/jose/jws/general/signer.js';
import { Jws } from '../../src/utils/jws.js';
import sinon from 'sinon';
describe('Auth', () => {
    if (process.env.TESTSOFF === 'false') {
        return;
    }
    describe('validateAuthorizationIntegrity()', () => {
        it('should throw if given message does not have `authorization` property', () => __awaiter(void 0, void 0, void 0, function* () {
            // create a message without `authorization`
            const recordsRead = yield RecordsRead.create({
                recordId: yield TestDataGenerator.randomCborSha256Cid()
            });
            yield expect(validateAuthorizationIntegrity(recordsRead.message)).to.be.rejectedWith(DwnErrorCode.AuthorizationMissing);
        }));
    });
    describe('authenticate()', () => {
        it('should pass with given JWS', () => __awaiter(void 0, void 0, void 0, function* () {
            var _a, _b, _c;
            const user = {
                alias: 'aaa47@mailinator.com',
                id: 'did:ion:EiBdFluTM1eWeCp6eOEoI6apCtISBorYJc6YGqxoZpcuOQ:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJkd24iLCJwdWJsaWNLZXlKd2siOnsiY3J2Ijoic2VjcDI1NmsxIiwia3R5IjoiRUMiLCJ4IjoiX2Zsd2k2RjFjenE0Y0JvVGI1X184cmJlcDJhT0ZYYlc5aVhDejFyZXhNcyIsInkiOiI3dmdMSmVvM2J1QlNBQVlQOWUxanZuS3JGY0Y4OFpZSlVxMlBiNmpBRmJFIn0sInB1cnBvc2VzIjpbImF1dGhlbnRpY2F0aW9uIl0sInR5cGUiOiJKc29uV2ViS2V5MjAyMCJ9XSwic2VydmljZXMiOlt7ImlkIjoiZHduIiwic2VydmljZUVuZHBvaW50Ijp7Im5vZGVzIjpbImh0dHA6Ly9sb2NhbGhvc3Q6ODA4NSJdfSwidHlwZSI6IkRlY2VudHJhbGl6ZWRXZWJOb2RlIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlCY3RPODVXZElSMVUxODNpb1BLeWdnb09uN3lwZVhQbEhJVG5CU0N0YXYzQSJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpRF9xUkhyWm9sN2NQRlJvQVFhWGpDRFdpblVRSkxzQmlkMXlSZTZyQVdDVEEiLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUI1TklpUzdwVk1pZ3V0ZHdmUWtOSnV6VHExRUZlb2MzZkIzTktMelY5aThRIn19',
                token: '1234567890',
                deviceId: '0987654321',
            };
            const exchange = { 'id': 'did:ion:EiB4_BNGwacnMYu00oapwN_6gpu8Hg1clLujF1bVXqOlmw:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJkd24iLCJwdWJsaWNLZXlKd2siOnsiY3J2Ijoic2VjcDI1NmsxIiwia3R5IjoiRUMiLCJ4IjoiYWwtNi1rV2R5MWVDT29wLUFENXB5V2stX1BjSzNxN2RxWTZZc0MyWThlMCIsInkiOiJRMWp1UjU1T0RiZUlVQ18zMGtsZHZsZEFhY0VOMnpwZE5KcThFWS16cjZ3In0sInB1cnBvc2VzIjpbImF1dGhlbnRpY2F0aW9uIl0sInR5cGUiOiJKc29uV2ViS2V5MjAyMCJ9XX19XSwidXBkYXRlQ29tbWl0bWVudCI6IkVpQ2tiZXZtT3VKeE5qZzh6YUxFQW9POTFzMkk4Z05RWFUxVmhMdzBzWVZYZ2cifSwic3VmZml4RGF0YSI6eyJkZWx0YUhhc2giOiJFaUQyMmFiSWcwZDItTjh4RERzci1ZUklXdWRmWVBjN1lXTmViLUFpRlM0VGtBIiwicmVjb3ZlcnlDb21taXRtZW50IjoiRWlBWG5xSDFwMXkwSVpoRFE5VVBIRVBkWG4yNHJlY08zamlkMUZ1RmstMWtGdyJ9fQ', 'internalId': 'did:ion:EiB4_BNGwacnMYu00oapwN_6gpu8Hg1clLujF1bVXqOlmw', 'methodData': [{ 'operation': 'create', 'content': { 'publicKeys': [{ 'id': 'dwn', 'type': 'JsonWebKey2020', 'purposes': ['authentication'], 'publicKeyJwk': { 'kty': 'EC', 'crv': 'secp256k1', 'x': 'al-6-kWdy1eCOop-AD5pyWk-_PcK3q7dqY6YsC2Y8e0', 'y': 'Q1juR55ODbeIUC_30kldvldAacEN2zpdNJq8EY-zr6w' } }] }, 'recovery': { 'publicJwk': { 'kty': 'EC', 'crv': 'secp256k1', 'x': 'WWqtvBTyZ6A7NkUyqPW9-OYKAwHpl4gniN3f6ZAXeww', 'y': 'HaDz6HdBzbVbzIxrjWiv3D8M5g-QtpxuljHfliPyKdE' }, 'privateJwk': { 'kty': 'EC', 'crv': 'secp256k1', 'x': 'WWqtvBTyZ6A7NkUyqPW9-OYKAwHpl4gniN3f6ZAXeww', 'y': 'HaDz6HdBzbVbzIxrjWiv3D8M5g-QtpxuljHfliPyKdE', 'd': 'jUmhgjdCBsk025eGiBo8t825UwpW8pUwghQv_9pXYPE' } }, 'update': { 'publicJwk': { 'kty': 'EC', 'crv': 'secp256k1', 'x': 'k4ee0m4R2bjsHLFAsknQUCNokIdGNdXaU1h-j06Z7nQ', 'y': 'zXbAlTNc8RXhSgXYevIABGY8DQVrJ6_uEpMMSO1f6e4' }, 'privateJwk': { 'kty': 'EC', 'crv': 'secp256k1', 'x': 'k4ee0m4R2bjsHLFAsknQUCNokIdGNdXaU1h-j06Z7nQ', 'y': 'zXbAlTNc8RXhSgXYevIABGY8DQVrJ6_uEpMMSO1f6e4', 'd': 'fmvoCvkb4n_41y-Eu9ABefgOiAy_y5l9Ql70IVHzM08' } } }], 'keys': [{ 'id': 'dwn', 'type': 'JsonWebKey2020', 'keyPair': { 'publicJwk': { 'kty': 'EC', 'crv': 'secp256k1', 'x': 'al-6-kWdy1eCOop-AD5pyWk-_PcK3q7dqY6YsC2Y8e0', 'y': 'Q1juR55ODbeIUC_30kldvldAacEN2zpdNJq8EY-zr6w' }, 'privateJwk': { 'kty': 'EC', 'crv': 'secp256k1', 'x': 'al-6-kWdy1eCOop-AD5pyWk-_PcK3q7dqY6YsC2Y8e0', 'y': 'Q1juR55ODbeIUC_30kldvldAacEN2zpdNJq8EY-zr6w', 'd': '9Hk675XwfDyy2LcRWTwKoBDBTYcq1MdnSvIMuHuzreY' } }, 'purposes': ['authentication'] }], 'services': [] };
            expect(() => Did.validate(exchange.id)).to.not.throw();
            const didIonResolver = new DidIonResolver();
            const sig = {
                // @ts-ignore
                privateJwk: exchange.keys.find((key) => key.id === 'dwn').keyPair.privateJwk,
                protectedHeader: { alg: 'ES256K', kid: `${exchange.id}#dwn`, typ: 'JWT' },
            };
            sig.privateJwk.alg = 'EdDSA';
            const networkAvailable = false;
            // stub network call if network is not available
            if (!networkAvailable) {
                sinon.stub(globalThis, 'fetch').resolves({
                    status: 200,
                    json: () => __awaiter(void 0, void 0, void 0, function* () {
                        return Promise.resolve({
                            didDocument: { id: exchange.id },
                            didDocumentMetadata: { canonicalId: exchange.id }
                        });
                    })
                });
            }
            const resolutionDocument = yield didIonResolver.resolve(exchange.id);
            const definition = {
                protocol: 'authentication',
                types: {
                    message: {
                        schema: 'authentication/message',
                        dataFormats: ['application/json']
                    }
                },
                structure: {
                    message: {
                        '$actions': [
                            {
                                who: 'anyone',
                                can: 'read',
                            },
                            {
                                who: 'anyone',
                                can: 'write',
                            }
                        ]
                    }
                }
            };
            const { message } = yield TestDataGenerator.generateRecordsWrite({ recipient: exchange.id, protocol: definition.protocol, protocolPath: 'message' });
            const recordsRead = yield RecordsRead.create({
                recordId: message.recordId,
                authorizationSignatureInput: sig
            });
            yield expect(validateAuthorizationIntegrity(recordsRead.message)).to.not.be.rejectedWith(DwnErrorCode.AuthorizationMissing);
            expect((_a = resolutionDocument.didDocument) === null || _a === void 0 ? void 0 : _a.id).to.equal(exchange.id);
            const verificationMethod = (_b = resolutionDocument.didDocument) === null || _b === void 0 ? void 0 : _b.verificationMethod[0];
            expect((_c = verificationMethod.publicKeyJwk) === null || _c === void 0 ? void 0 : _c.x).to.equal(exchange.keys[0].keyPair.publicJwk.x);
            const payloadBytes = new TextEncoder().encode(JSON.stringify({ alias: user.alias, identity: user.id, appId: '3', authMode: 5, token: user.token, deviceId: user.deviceId }));
            const signer = yield GeneralJwsSigner.create(payloadBytes, [{ privateJwk: sig.privateJwk, protectedHeader: sig.protectedHeader }]);
            const jws = signer.getJws();
            // const jwt = `${jws.signatures[0].protected}.${jws.payload}`;
            // console.log('JWT', jwt);
            console.log('authenticate', yield authenticate(jws, new DidResolver));
            yield expect(authenticate(jws, new DidResolver)).to.not.be.rejectedWith(DwnErrorCode.AuthenticateJwsMissing);
            const token = yield GeneralJwsSigner.signJWT({
                exp: Math.floor(Date.now() / 1000) + 86000,
                loginExp: Math.floor(Date.now() / 1000) + 86000,
                data: user.alias,
                sub: 'did:ion:EiBdFluTM1eWeCp6eOEoI6apCtISBorYJc6YGqxoZpcuOQ',
                iss: 'auth',
                signature: jws.signatures[0].protected,
            });
            console.log('jwt token', token);
            console.log('verify', yield GeneralJwsSigner.verifyJWT(token));
        }));
        it('should throw if given JWS is `undefined`', () => __awaiter(void 0, void 0, void 0, function* () {
            var _d, _e, _f;
            return;
            const bob = yield DidKeyResolver.generate();
            expect(() => Did.validate(bob.did)).to.not.throw();
            const didKeyResolver = new DidKeyResolver();
            const sig = Jws.createSignatureInput(bob);
            const networkAvailable = false;
            // stub network call if network is not available
            if (!networkAvailable) {
                sinon.stub(globalThis, 'fetch').resolves({
                    status: 200,
                    json: () => __awaiter(void 0, void 0, void 0, function* () {
                        return Promise.resolve({
                            didDocument: { id: bob.did },
                            didDocumentMetadata: { canonicalId: bob.did }
                        });
                    })
                });
            }
            const resolutionDocument = yield didKeyResolver.resolve(bob.did);
            console.log('resolutionDocument', JSON.stringify(resolutionDocument, null, 2));
            const { message } = yield TestDataGenerator.generateRecordsWrite({ author: bob });
            const recordsRead = yield RecordsRead.create({
                recordId: message.recordId,
                authorizationSignatureInput: sig
            });
            yield expect(validateAuthorizationIntegrity(recordsRead.message)).to.not.be.rejectedWith(DwnErrorCode.AuthorizationMissing);
            expect((_d = resolutionDocument.didDocument) === null || _d === void 0 ? void 0 : _d.id).to.equal(bob.did);
            const verificationMethod = (_e = resolutionDocument.didDocument) === null || _e === void 0 ? void 0 : _e.verificationMethod[0];
            expect((_f = verificationMethod.publicKeyJwk) === null || _f === void 0 ? void 0 : _f.x).to.equal(bob.keyPair.publicJwk.x);
            const jws = undefined;
            yield expect(authenticate(jws, new DidResolver)).to.be.rejectedWith(DwnErrorCode.AuthenticateJwsMissing);
        }));
    });
});
//# sourceMappingURL=auth.spec.js.map