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 { expect } from 'chai';
import { PermissionsConditionPublication } from '../../src/types/permissions-types.js';
import { PermissionsGrant } from '../../src/interfaces/permissions-grant.js';
import { Secp256k1 } from '../../src/utils/secp256k1.js';
import { TestDataGenerator } from '../utils/test-data-generator.js';
import { Time } from '../../src/utils/time.js';
import { DidKeyResolver, DwnErrorCode, Jws, PrivateKeySigner } from '../../src/index.js';
import { DwnInterfaceName, DwnMethodName, Message } from '../../src/core/message.js';
describe('PermissionsGrant', () => {
    if (process.env.TESTSOFF === 'true') {
        return;
    }
    describe('create()', () => __awaiter(void 0, void 0, void 0, function* () {
        it('creates a PermissionsGrant message', () => __awaiter(void 0, void 0, void 0, function* () {
            const { privateJwk } = yield Secp256k1.generateKeyPair();
            const signer = new PrivateKeySigner({ privateJwk, keyId: 'did:key:bob' });
            const { message } = yield PermissionsGrant.create({
                dateExpires: Time.getCurrentTimestamp(),
                description: 'perms',
                grantedBy: 'did:key:bob',
                grantedTo: 'did:key:alice',
                grantedFor: 'did:key:bob',
                scope: { interface: DwnInterfaceName.Records, method: DwnMethodName.Write },
                signer
            });
            expect(message.descriptor.grantedTo).to.equal('did:key:alice');
            expect(message.descriptor.grantedBy).to.equal('did:key:bob');
            expect(message.descriptor.scope).to.eql({ interface: DwnInterfaceName.Records, method: DwnMethodName.Write });
            expect(message.descriptor.conditions).to.be.undefined;
            expect(message.descriptor.description).to.eql('perms');
        }));
        describe('scope property normalizations', () => __awaiter(void 0, void 0, void 0, function* () {
            it('ensures that `schema` is normalized', () => __awaiter(void 0, void 0, void 0, function* () {
                const { privateJwk } = yield Secp256k1.generateKeyPair();
                const signer = new PrivateKeySigner({ privateJwk, keyId: 'did:key:bob' });
                const scope = {
                    interface: DwnInterfaceName.Records,
                    method: DwnMethodName.Write,
                    schema: 'example.com/',
                };
                const { message } = yield PermissionsGrant.create({
                    dateExpires: Time.getCurrentTimestamp(),
                    description: 'schema normalization test',
                    grantedBy: 'did:key:bob',
                    grantedTo: 'did:key:alice',
                    grantedFor: 'did:key:bob',
                    scope: scope,
                    signer
                });
                expect(message.descriptor.scope.schema).to.equal('http://example.com');
            }));
            it('ensures that `protocol` is normalized', () => __awaiter(void 0, void 0, void 0, function* () {
                const { privateJwk } = yield Secp256k1.generateKeyPair();
                const signer = new PrivateKeySigner({ privateJwk, keyId: 'did:key:bob' });
                const scope = {
                    interface: DwnInterfaceName.Records,
                    method: DwnMethodName.Write,
                    protocol: 'example.com/',
                };
                const { message } = yield PermissionsGrant.create({
                    dateExpires: Time.getCurrentTimestamp(),
                    description: 'protocol normalization test',
                    grantedBy: 'did:key:bob',
                    grantedTo: 'did:key:alice',
                    grantedFor: 'did:key:bob',
                    scope: scope,
                    signer
                });
                expect(message.descriptor.scope.protocol).to.equal('http://example.com');
            }));
        }));
        describe('scope validations', () => {
            it('ensures that `schema` and protocol related fields `protocol`, `contextId` or `protocolPath`', () => __awaiter(void 0, void 0, void 0, function* () {
                const { privateJwk } = yield Secp256k1.generateKeyPair();
                const signer = new PrivateKeySigner({ privateJwk, keyId: 'did:key:bob' });
                const permissionsGrantOptions = {
                    dateExpires: Time.getCurrentTimestamp(),
                    grantedBy: 'did:key:bob',
                    grantedTo: 'did:key:alice',
                    grantedFor: 'did:key:bob',
                    signer
                };
                // Reject when `schema` and `protocol` are both present
                let scope = {
                    interface: DwnInterfaceName.Records,
                    method: DwnMethodName.Write,
                    schema: 'some-schema',
                    protocol: 'some-protocol'
                };
                expect(PermissionsGrant.create(Object.assign(Object.assign({}, permissionsGrantOptions), { scope })))
                    .to.be.rejectedWith(DwnErrorCode.PermissionsGrantScopeSchemaProhibitedFields);
                // Reject when `schema` and `contextId` are both present
                scope = {
                    interface: DwnInterfaceName.Records,
                    method: DwnMethodName.Write,
                    schema: 'some-schema',
                    contextId: 'some-contextId'
                };
                expect(PermissionsGrant.create(Object.assign(Object.assign({}, permissionsGrantOptions), { scope })))
                    .to.be.rejectedWith(DwnErrorCode.PermissionsGrantScopeSchemaProhibitedFields);
                // Reject when `schema` and `protocolPath` are both present
                scope = {
                    interface: DwnInterfaceName.Records,
                    method: DwnMethodName.Write,
                    schema: 'some-schema',
                    protocolPath: 'some-protocol-path'
                };
                expect(PermissionsGrant.create(Object.assign(Object.assign({}, permissionsGrantOptions), { scope })))
                    .to.be.rejectedWith(DwnErrorCode.PermissionsGrantScopeSchemaProhibitedFields);
            }));
            it('ensures that `contextId` and `protocolPath` are not both present', () => __awaiter(void 0, void 0, void 0, function* () {
                const { privateJwk } = yield Secp256k1.generateKeyPair();
                const signer = new PrivateKeySigner({ privateJwk, keyId: 'did:key:bob' });
                const permissionsGrantOptions = {
                    dateExpires: Time.getCurrentTimestamp(),
                    grantedBy: 'did:key:bob',
                    grantedTo: 'did:key:alice',
                    grantedFor: 'did:key:bob',
                    signer
                };
                // Allow when `context to be present ` and `protocol` are both present
                const scope = {
                    interface: DwnInterfaceName.Records,
                    method: DwnMethodName.Write,
                    protocol: 'some-protocol',
                    contextId: 'some-contextId',
                    protocolPath: 'some-protocol-path',
                };
                expect(PermissionsGrant.create(Object.assign(Object.assign({}, permissionsGrantOptions), { scope })))
                    .to.be.rejectedWith(DwnErrorCode.PermissionsGrantScopeContextIdAndProtocolPath);
            }));
        });
    }));
    describe('createFromPermissionsRequest()', () => __awaiter(void 0, void 0, void 0, function* () {
        it('should create a PermissionsGrant from a PermissionsRequest with the same properties', () => __awaiter(void 0, void 0, void 0, function* () {
            const alice = yield TestDataGenerator.generatePersona();
            const bob = yield TestDataGenerator.generatePersona();
            const { privateJwk } = yield Secp256k1.generateKeyPair();
            const signer = new PrivateKeySigner({ privateJwk, keyId: alice.did });
            const { permissionsRequest } = yield TestDataGenerator.generatePermissionsRequest({
                author: bob,
                description: 'friendship',
                grantedBy: alice.did,
                grantedFor: alice.did,
                grantedTo: bob.did,
            });
            const dateExpires = Time.createOffsetTimestamp({ seconds: 60 * 60 * 24 });
            const permissionsGrant = yield PermissionsGrant.createFromPermissionsRequest(permissionsRequest, signer, { dateExpires });
            expect(permissionsGrant.author).to.eq(alice.did);
            expect(permissionsGrant.message.descriptor.description).to.eq(permissionsRequest.message.descriptor.description);
            expect(permissionsGrant.message.descriptor.grantedBy).to.eq(permissionsRequest.message.descriptor.grantedBy);
            expect(permissionsGrant.message.descriptor.grantedTo).to.eq(permissionsRequest.message.descriptor.grantedTo);
            expect(permissionsGrant.message.descriptor.grantedFor).to.eq(permissionsRequest.message.descriptor.grantedFor);
            expect(permissionsGrant.message.descriptor.scope).to.eql(permissionsRequest.message.descriptor.scope);
            expect(permissionsGrant.message.descriptor.conditions).to.eq(permissionsRequest.message.descriptor.conditions);
            expect(permissionsGrant.message.descriptor.permissionsRequestId).to.eq(yield Message.getCid(permissionsRequest.message));
        }));
        it('should create a PermissionsGrant from a PermissionsRequest and overrides', () => __awaiter(void 0, void 0, void 0, function* () {
            const alice = yield DidKeyResolver.generate();
            const bob = yield DidKeyResolver.generate();
            const carol = yield DidKeyResolver.generate();
            const { privateJwk } = yield Secp256k1.generateKeyPair();
            const signer = new PrivateKeySigner({ privateJwk, keyId: `${alice.did}#key1` });
            const { permissionsRequest } = yield TestDataGenerator.generatePermissionsRequest();
            const description = 'friendship';
            const dateExpires = Time.getCurrentTimestamp();
            const overrides = {
                dateExpires,
                description,
                grantedBy: alice.did,
                grantedTo: bob.did,
                grantedFor: carol.did,
                scope: {
                    interface: DwnInterfaceName.Protocols,
                    method: DwnMethodName.Query,
                },
                conditions: {
                    publication: PermissionsConditionPublication.Required,
                }
            };
            const permissionsGrant = yield PermissionsGrant.createFromPermissionsRequest(permissionsRequest, signer, overrides);
            expect(permissionsGrant.author).to.eq(alice.did);
            expect(permissionsGrant.message.descriptor.description).to.eq(description);
            expect(permissionsGrant.message.descriptor.grantedBy).to.eq(overrides.grantedBy);
            expect(permissionsGrant.message.descriptor.grantedTo).to.eq(overrides.grantedTo);
            expect(permissionsGrant.message.descriptor.grantedFor).to.eq(overrides.grantedFor);
            expect(permissionsGrant.message.descriptor.scope).to.eql(overrides.scope);
            expect(permissionsGrant.message.descriptor.conditions).to.eq(overrides.conditions);
            expect(permissionsGrant.message.descriptor.permissionsRequestId).to.eq(yield Message.getCid(permissionsRequest.message));
        }));
    }));
    describe('asDelegatedGrant()', () => __awaiter(void 0, void 0, void 0, function* () {
        it('should throw if the `delegated` property is not `true`', () => __awaiter(void 0, void 0, void 0, function* () {
            const alice = yield TestDataGenerator.generatePersona();
            const { message } = yield PermissionsGrant.create({
                dateExpires: Time.getCurrentTimestamp(),
                grantedBy: alice.did,
                grantedTo: 'did:example:bob',
                grantedFor: alice.did,
                scope: { interface: DwnInterfaceName.Records, method: DwnMethodName.Write },
                signer: Jws.createSigner(alice)
            });
            expect(() => PermissionsGrant.asDelegatedGrant(message)).to.throw(DwnErrorCode.PermissionsGrantNotADelegatedGrant);
        }));
    }));
});
//# sourceMappingURL=permissions-grant.spec.js.map