Pomoc z UserReferencedInField

Hej! Próbuje właśnie zrobić w jednej z aplikacji przy której pracuje poza sealcodem tak aby użyktownik mógł wylistować siebie lub tych użytkowników, których on sam utworzył. Informację o tym kto udtworzył danego użytkownika trzymam w polu created_by. Kolkecja wygląda tak

import { App, Collections, FieldTypes, Policies } from "sealious";

class Users extends Collections.users {
    fields = {
        ...App.BaseCollections.users.fields,
        photo: new FieldTypes.File(),
        name: FieldTypes.Required(new FieldTypes.Text()),
        surname: FieldTypes.Required(new FieldTypes.Text()),
        email: FieldTypes.Required(new FieldTypes.Email()),
        roles: new FieldTypes.ReverseSingleReference({
            referencing_collection: "user-roles",
            referencing_field: "user",
        }),
        created_by: new FieldTypes.SingleReference("users"),
    };

    policies = {
        list: new Policies.Or([
            new Policies.Themselves(),
            new Policies.UserReferencedInField("created_by"),
        ]),
    };

    defaultPolicy = new Policies.Public();
}

export default new Users();

Czy dobrze używam policy UserReferencedInField? Oraz czy pole typu SingleReference może być puste? Na ten moment jak próbuje utowrzyć użytkowników po utworzeniu tego pola dostaje taki błąd

ewaluator-test-1         |   1) Collections: users collection
ewaluator-test-1         |        lector should only be able to list his melodycs:
ewaluator-test-1         |      Error: Invalid field values
ewaluator-test-1         |       at CollectionItem.throwIfInvalid (node_modules/sealious/src/chip-types/collection-item.ts:96:10)
ewaluator-test-1         |       at processTicksAndRejections (node:internal/process/task_queues:96:5)
ewaluator-test-1         |       at async CollectionItem.save (node_modules/sealious/src/chip-types/collection-item.ts:152:4)
ewaluator-test-1         |       at async populate (backend/utlis/mock.ts:35:19)
ewaluator-test-1         |       at async exports.default (backend/utlis/mock.ts:125:9)
ewaluator-test-1         |       at async withTestApp (backend/utlis/test.ts:24:5)
ewaluator-test-1         |       at async Context.<anonymous> (backend/collections/users.test.ts:16:9)

a nie moge podac kto utworzył pierwszego admina. Przez to te pole nie jest wymagane

Informacja o tym, kto utworzył dany item w kolekcji jest już trzymana w dodawanym do każdego itema pola _metadata.

Policy odpowiedzialną za dostęp tylko do tych zasobów, które utworzył aktualnie zalogowany użytkownik jest Owner - sprawdź, czy działa tak, jakbys chciał :slight_smile:

Alternatywnym podejściem byłoby utworzenie pola typu ReverseSingleReference dla każdego użytkownika i ładowanie go attachmentsaim. Ale użycie policy Owner powinno być znacznie prostsze :+1:

Poprawiłem policy na takie

import { App, Collections, FieldTypes, Policies } from "sealious";

class Users extends Collections.users {
    fields = {
        ...App.BaseCollections.users.fields,
        photo: new FieldTypes.File(),
        name: FieldTypes.Required(new FieldTypes.Text()),
        surname: FieldTypes.Required(new FieldTypes.Text()),
        email: FieldTypes.Required(new FieldTypes.Email()),
        roles: new FieldTypes.ReverseSingleReference({
            referencing_collection: "user-roles",
            referencing_field: "user",
        }),
    };

    policies = {
        list: new Policies.Or([
            new Policies.Themselves(),
            new Policies.Owner(),
        ]),
    };

    defaultPolicy = new Policies.Public();
}

export default new Users();

I teraz mi się wywala jak próbuje utworzyć użytkownika za pomocą kontekstu admina

    const lector = await app.collections.users.create(
        new Context(app, new Date().getTime(), admin.id),
        {
            username: "lector",
            name: loremIpsum.generateWords(1),
            surname: loremIpsum.generateWords(1),
            email: `${loremIpsum.generateWords(1)}@${loremIpsum.generateWords(
                1
            )}.${loremIpsum.generateWords(1)}`,
            password: "pass1234567",
            photo: lecturePhoto,
            roles: [],
        }
    );

Admin do którego się odwołuje zostaju poprawnie utworzony za pomocą super kontekstu. Dostaje taką wiadomość

ewaluator-test-1         |  STARTED  App running. URL set in manifest: http://localhost:8080
ewaluator-test-1         |     2) lector should only be able to list his melodycs
ewaluator-test-1         | 
ewaluator-test-1         | 
ewaluator-test-1         |   0 passing (432ms)
ewaluator-test-1         |   2 failing
ewaluator-test-1         | 
ewaluator-test-1         |   1) Collections: users collection
ewaluator-test-1         |        admin should be able to list everyone:
ewaluator-test-1         |      Error: This is a read-only field
ewaluator-test-1         |       at ReverseSingleReference.isProperValue (node_modules/sealious/src/app/base-chips/field-types/cached-value.ts:196:10)
ewaluator-test-1         |       at ReverseSingleReference.checkValue (node_modules/sealious/src/chip-types/field.ts:142:16)
ewaluator-test-1         |       at CollectionItemBody.validate (node_modules/sealious/src/chip-types/collection-item-body.ts:196:7)
ewaluator-test-1         |       at CollectionItem.throwIfInvalid (node_modules/sealious/src/chip-types/collection-item.ts:85:45)
ewaluator-test-1         |       at CollectionItem.save (node_modules/sealious/src/chip-types/collection-item.ts:152:15)
ewaluator-test-1         |       at processTicksAndRejections (node:internal/process/task_queues:96:5)
ewaluator-test-1         |       at async populate (backend/utlis/mock.ts:52:20)
ewaluator-test-1         |       at async exports.default (backend/utlis/mock.ts:125:9)
ewaluator-test-1         |       at async withTestApp (backend/utlis/test.ts:24:5)
ewaluator-test-1         |       at async Context.<anonymous> (backend/collections/users.test.ts:6:9)

Zrób na tym try/catch i daj console.error na rzucony błąd. W metadanych błędu powinny być kluczowe dla diagnozy informacje

ewaluator-test-1         | BadContext [Error]: This is a read-only field
ewaluator-test-1         |     at ReverseSingleReference.isProperValue (/usr/src/service/node_modules/sealious/src/app/base-chips/field-types/cached-value.ts:196:10)
ewaluator-test-1         |     at ReverseSingleReference.checkValue (/usr/src/service/node_modules/sealious/src/chip-types/field.ts:142:16)
ewaluator-test-1         |     at CollectionItemBody.validate (/usr/src/service/node_modules/sealious/src/chip-types/collection-item-body.ts:196:7)
ewaluator-test-1         |     at CollectionItem.throwIfInvalid (/usr/src/service/node_modules/sealious/src/chip-types/collection-item.ts:85:45)
ewaluator-test-1         |     at CollectionItem.save (/usr/src/service/node_modules/sealious/src/chip-types/collection-item.ts:152:15)
ewaluator-test-1         |     at processTicksAndRejections (node:internal/process/task_queues:96:5)
ewaluator-test-1         |     at async populate (/usr/src/service/backend/utlis/mock.ts:53:24)
ewaluator-test-1         |     at async exports.default (/usr/src/service/backend/utlis/mock.ts:131:9)
ewaluator-test-1         |     at async withTestApp (/usr/src/service/backend/utlis/test.ts:24:5)
ewaluator-test-1         |     at async Context.<anonymous> (/usr/src/service/backend/collections/users.test.ts:6:9) {
ewaluator-test-1         |   sealious_error: true,
ewaluator-test-1         |   is_user_fault: true,
ewaluator-test-1         |   type: 'permission',
ewaluator-test-1         |   data: {},
ewaluator-test-1         |   is_developer_fault: false
ewaluator-test-1         | }

Nie wiem czy to jakoś bardzo pomaga, nadal nie wiem o jakie pole chodzi

Spróbuj przy tworzeniu nie podawać wartości pola roles

Pomogło, dzięki!

1 Like