@authup/server-core 1.0.0-beta.38 → 1.0.0-beta.39
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.
- package/dist/adapters/http/adapters/index.mjs +2 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/authorize.d.ts +2 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/authorize.d.ts.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/authorize.mjs +10 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/authorize.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.d.ts.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.mjs +5 -13
- package/dist/adapters/http/adapters/oauth2/grant-types/client-credentials.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/index.mjs +2 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/password.d.ts +2 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/password.d.ts.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs +11 -2
- package/dist/adapters/http/adapters/oauth2/grant-types/password.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.d.ts +5 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.d.ts.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs +19 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/refresh_token.mjs.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/types.d.ts +6 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/types.d.ts.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.d.ts +15 -0
- package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.d.ts.map +1 -0
- package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.mjs +57 -0
- package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.mjs.map +1 -0
- package/dist/adapters/http/adapters/oauth2/grant-types/utils/guess.mjs +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/utils/index.d.ts +1 -0
- package/dist/adapters/http/adapters/oauth2/grant-types/utils/index.d.ts.map +1 -1
- package/dist/adapters/http/adapters/oauth2/grant-types/utils/index.mjs +2 -1
- package/dist/adapters/http/adapters/oauth2/index.mjs +2 -1
- package/dist/adapters/http/controllers/entities/client/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/client/module.mjs +1 -1
- package/dist/adapters/http/controllers/entities/client/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/policy/utils/validation.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/policy/utils/validation.mjs +1 -1
- package/dist/adapters/http/controllers/entities/policy/utils/validation.mjs.map +1 -1
- package/dist/adapters/http/controllers/entities/robot/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/entities/robot/module.mjs +1 -1
- package/dist/adapters/http/controllers/entities/robot/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/token/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/token/module.mjs +4 -1
- package/dist/adapters/http/controllers/workflows/token/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/token/types.d.ts +2 -1
- package/dist/adapters/http/controllers/workflows/token/types.d.ts.map +1 -1
- package/dist/adapters/http/index.mjs +2 -1
- package/dist/app/modules/database/repositories/client/repository.d.ts +1 -0
- package/dist/app/modules/database/repositories/client/repository.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/client/repository.mjs +40 -1
- package/dist/app/modules/database/repositories/client/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/permission/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/permission/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/policy/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/policy/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/realm/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/realm/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/robot/repository.d.ts +1 -0
- package/dist/app/modules/database/repositories/robot/repository.d.ts.map +1 -1
- package/dist/app/modules/database/repositories/robot/repository.mjs +32 -1
- package/dist/app/modules/database/repositories/robot/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/role/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/role/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/scope/repository.mjs +1 -1
- package/dist/app/modules/database/repositories/scope/repository.mjs.map +1 -1
- package/dist/app/modules/database/repositories/user/repository.mjs +2 -2
- package/dist/app/modules/database/repositories/user/repository.mjs.map +1 -1
- package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
- package/dist/app/modules/http/modules/controller.mjs +2 -0
- package/dist/app/modules/http/modules/controller.mjs.map +1 -1
- package/dist/core/entities/client/service.d.ts +1 -1
- package/dist/core/entities/client/service.d.ts.map +1 -1
- package/dist/core/entities/client/service.mjs +12 -19
- package/dist/core/entities/client/service.mjs.map +1 -1
- package/dist/core/entities/client/types.d.ts +2 -1
- package/dist/core/entities/client/types.d.ts.map +1 -1
- package/dist/core/entities/robot/service.d.ts +1 -1
- package/dist/core/entities/robot/service.d.ts.map +1 -1
- package/dist/core/entities/robot/service.mjs +12 -18
- package/dist/core/entities/robot/service.mjs.map +1 -1
- package/dist/core/entities/robot/types.d.ts +2 -1
- package/dist/core/entities/robot/types.d.ts.map +1 -1
- package/dist/core/entities/user/service.d.ts.map +1 -1
- package/dist/core/entities/user/service.mjs +10 -13
- package/dist/core/entities/user/service.mjs.map +1 -1
- package/dist/core/identity/password-recovery/service.d.ts.map +1 -1
- package/dist/core/identity/password-recovery/service.mjs +4 -4
- package/dist/core/identity/password-recovery/service.mjs.map +1 -1
- package/dist/core/identity/provider/account/module.d.ts.map +1 -1
- package/dist/core/identity/provider/account/module.mjs +3 -2
- package/dist/core/identity/provider/account/module.mjs.map +1 -1
- package/dist/core/index.mjs +2 -1
- package/dist/core/oauth2/authorization/code/verifier/module.d.ts.map +1 -1
- package/dist/core/oauth2/authorization/code/verifier/module.mjs +8 -4
- package/dist/core/oauth2/authorization/code/verifier/module.mjs.map +1 -1
- package/dist/core/oauth2/authorization/code/verifier/types.d.ts +2 -0
- package/dist/core/oauth2/authorization/code/verifier/types.d.ts.map +1 -1
- package/dist/core/oauth2/authorization/code-request/verifier/module.d.ts.map +1 -1
- package/dist/core/oauth2/authorization/code-request/verifier/module.mjs +7 -1
- package/dist/core/oauth2/authorization/code-request/verifier/module.mjs.map +1 -1
- package/dist/core/oauth2/client/authenticator.d.ts +17 -0
- package/dist/core/oauth2/client/authenticator.d.ts.map +1 -0
- package/dist/core/oauth2/client/authenticator.mjs +34 -0
- package/dist/core/oauth2/client/authenticator.mjs.map +1 -0
- package/dist/core/oauth2/client/index.d.ts +1 -0
- package/dist/core/oauth2/client/index.d.ts.map +1 -1
- package/dist/core/oauth2/client/index.mjs +2 -1
- package/dist/core/oauth2/grant-types/password.d.ts +7 -3
- package/dist/core/oauth2/grant-types/password.d.ts.map +1 -1
- package/dist/core/oauth2/grant-types/password.mjs +9 -7
- package/dist/core/oauth2/grant-types/password.mjs.map +1 -1
- package/dist/core/oauth2/index.mjs +3 -1
- package/dist/core/oauth2/token/issuer/base.d.ts.map +1 -1
- package/dist/core/oauth2/token/issuer/base.mjs +3 -2
- package/dist/core/oauth2/token/issuer/base.mjs.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/ui/client/assets/index-Noe7uiOY.js +41 -0
- package/dist/ui/client/index.html +1 -1
- package/dist/ui/server/server.js +21 -7
- package/package.json +9 -9
- package/dist/ui/client/assets/index-AHa03lX_.js +0 -41
|
@@ -51,29 +51,22 @@ var ClientService = class extends AbstractEntityService {
|
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
async getOne(idOrName, actor, realmId) {
|
|
55
|
-
|
|
54
|
+
async getOne(idOrName, actor, query, realmId) {
|
|
55
|
+
const permissionNames = [
|
|
56
56
|
PermissionName.CLIENT_READ,
|
|
57
57
|
PermissionName.CLIENT_UPDATE,
|
|
58
58
|
PermissionName.CLIENT_DELETE
|
|
59
|
-
]
|
|
60
|
-
let
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
const realm = await this.realmRepository.resolve(realmId);
|
|
64
|
-
if (realm) entity = await this.repository.findOneBy({
|
|
65
|
-
name: idOrName,
|
|
66
|
-
realm_id: realm.id
|
|
67
|
-
});
|
|
68
|
-
else entity = null;
|
|
69
|
-
} else entity = await this.repository.findOneByName(idOrName);
|
|
59
|
+
];
|
|
60
|
+
let isMe = !!actor.identity && actor.identity.type === "client" && (actor.identity.data.id === idOrName || actor.identity.data.name === idOrName);
|
|
61
|
+
if (!isMe) await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });
|
|
62
|
+
const entity = await this.repository.findOne(idOrName, query, realmId);
|
|
70
63
|
if (!entity) throw new NotFoundError();
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
if (isMe && actor.identity.data.id !== entity.id) {
|
|
65
|
+
isMe = false;
|
|
66
|
+
await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });
|
|
67
|
+
}
|
|
68
|
+
if (!isMe && entity.secret && !entity.secret_encrypted && !entity.secret_hashed) await actor.permissionEvaluator.evaluateOneOf({
|
|
69
|
+
name: permissionNames,
|
|
77
70
|
input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity })
|
|
78
71
|
});
|
|
79
72
|
return entity;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PolicyData","isUUID","NotFoundError","ClientValidator","PermissionName","ValidatorGroup","AbstractEntityService","ClientCredentialsService","ClientService","repository","realmRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","CLIENT_READ","CLIENT_UPDATE","CLIENT_DELETE","data","entities","meta","findMany","total","entity","secret","secret_encrypted","secret_hashed","evaluateOneOf","input","ATTRIBUTES","push","getOne","idOrName","realmId","findOneByIdOrName","realm","resolve","findOneBy","realm_id","id","findOneByName","create","save","undefined","update","updateOnly","options","group","where","findOneWithSecret","isSelfEdit","preEvaluate","e","identity","type","CLIENT_SELF_MANAGE","UPDATE","CLIENT_CREATE","CREATE","validated","run","validateJoinColumns","checkUniqueness","credentialsService","actorRealmId","getActorRealmId","evaluate","merge","is_confidential","generateSecret","protect","created","delete","entityId","remove"],"sources":["../../../../src/core/entities/client/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, PolicyData } from '@authup/access';\nimport { isUUID } from '@authup/kit';\nimport { NotFoundError } from '@ebec/http';\nimport {\n ClientValidator,\n PermissionName,\n ValidatorGroup,\n} from '@authup/core-kit';\nimport type { Client } from '@authup/core-kit';\nimport type { ActorContext } from '../actor/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '../service.ts';\nimport type { EntityRepositoryFindManyResult } from '../types.ts';\nimport { ClientCredentialsService } from '../../authentication/credential/entities/client/module.ts';\nimport type { IClientRepository, IClientService } from './types.ts';\n\nexport type ClientServiceContext = {\n repository: IClientRepository;\n realmRepository: IRealmRepository;\n};\n\nexport class ClientService extends AbstractEntityService implements IClientService {\n protected repository: IClientRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: ClientValidator;\n\n constructor(ctx: ClientServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new ClientValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Client>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n });\n\n const {\n data: entities, \n meta, \n } = await this.repository.findMany(query);\n let { total } = meta;\n\n const data: Client[] = [];\n for (const entity of entities) {\n if (\n entity.secret &&\n !entity.secret_encrypted &&\n !entity.secret_hashed\n ) {\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n data.push(entity);\n } catch {\n total -= 1;\n }\n\n continue;\n }\n\n data.push(entity);\n }\n\n return {\n data,\n meta: {\n ...meta,\n total, \n }, \n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Client> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n });\n\n let entity: Client | null;\n\n if (isUUID(idOrName)) {\n entity = await this.repository.findOneByIdOrName(idOrName, realmId);\n } else if (realmId) {\n const realm = await this.realmRepository.resolve(realmId);\n if (realm) {\n entity = await this.repository.findOneBy({\n name: idOrName,\n realm_id: realm.id,\n });\n } else {\n entity = null;\n }\n } else {\n entity = await this.repository.findOneByName(idOrName);\n }\n\n if (!entity) {\n throw new NotFoundError();\n }\n\n if (\n entity.secret &&\n !entity.secret_encrypted &&\n !entity.secret_hashed\n ) {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Client> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Client> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Client,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realm_id === 'string' ?\n await this.realmRepository.resolve(data.realm_id) :\n undefined;\n\n let entity: Client | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realm_id = realm.id;\n }\n\n entity = await this.repository.findOneWithSecret(where);\n if (!entity && options.updateOnly) {\n throw new NotFoundError();\n }\n } else if (options.updateOnly) {\n throw new NotFoundError();\n }\n\n let isSelfEdit = false;\n if (entity) {\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_UPDATE });\n } catch (e) {\n if (\n !actor.identity ||\n actor.identity.type !== 'client' ||\n actor.identity.data.id !== entity.id\n ) {\n throw e;\n }\n isSelfEdit = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_SELF_MANAGE });\n }\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n await this.repository.checkUniqueness(validated, entity || undefined);\n\n const credentialsService = new ClientCredentialsService();\n\n if (entity) {\n if (\n !isSelfEdit &&\n !validated.realm_id &&\n !entity.realm_id\n ) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realm_id = actorRealmId;\n }\n }\n\n if (isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_SELF_MANAGE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n }\n\n entity = this.repository.merge(entity, validated);\n\n if (!isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_UPDATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n }\n\n if (entity.is_confidential) {\n if (!validated.secret && !entity.secret) {\n validated.secret = credentialsService.generateSecret();\n }\n\n if (validated.secret) {\n entity.secret = await credentialsService.protect(validated.secret, entity);\n }\n } else {\n entity.secret = null;\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!validated.realm_id) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realm_id = actorRealmId;\n }\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_CREATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n\n entity = this.repository.create(validated);\n\n if (entity.is_confidential) {\n if (!validated.secret) {\n validated.secret = credentialsService.generateSecret();\n }\n\n entity.secret = await credentialsService.protect(validated.secret, validated);\n } else {\n entity.secret = null;\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: true, \n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Client> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new NotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_DELETE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PolicyData","isUUID","NotFoundError","ClientValidator","PermissionName","ValidatorGroup","AbstractEntityService","ClientCredentialsService","ClientService","repository","realmRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","CLIENT_READ","CLIENT_UPDATE","CLIENT_DELETE","data","entities","meta","findMany","total","entity","secret","secret_encrypted","secret_hashed","evaluateOneOf","input","ATTRIBUTES","push","getOne","idOrName","realmId","permissionNames","isMe","identity","type","id","findOne","create","save","undefined","update","updateOnly","options","group","realm","realm_id","resolve","where","findOneWithSecret","isSelfEdit","preEvaluate","e","CLIENT_SELF_MANAGE","UPDATE","CLIENT_CREATE","CREATE","validated","run","validateJoinColumns","checkUniqueness","credentialsService","actorRealmId","getActorRealmId","evaluate","merge","is_confidential","generateSecret","protect","created","delete","findOneBy","entityId","remove"],"sources":["../../../../src/core/entities/client/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, PolicyData } from '@authup/access';\nimport { isUUID } from '@authup/kit';\nimport { NotFoundError } from '@ebec/http';\nimport {\n ClientValidator,\n PermissionName,\n ValidatorGroup,\n} from '@authup/core-kit';\nimport type { Client } from '@authup/core-kit';\nimport type { ActorContext } from '../actor/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '../service.ts';\nimport type { EntityRepositoryFindManyResult } from '../types.ts';\nimport { ClientCredentialsService } from '../../authentication/credential/entities/client/module.ts';\nimport type { IClientRepository, IClientService } from './types.ts';\n\nexport type ClientServiceContext = {\n repository: IClientRepository;\n realmRepository: IRealmRepository;\n};\n\nexport class ClientService extends AbstractEntityService implements IClientService {\n protected repository: IClientRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: ClientValidator;\n\n constructor(ctx: ClientServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new ClientValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Client>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n });\n\n const {\n data: entities, \n meta, \n } = await this.repository.findMany(query);\n let { total } = meta;\n\n const data: Client[] = [];\n for (const entity of entities) {\n if (\n entity.secret &&\n !entity.secret_encrypted &&\n !entity.secret_hashed\n ) {\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ],\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n data.push(entity);\n } catch {\n total -= 1;\n }\n\n continue;\n }\n\n data.push(entity);\n }\n\n return {\n data,\n meta: {\n ...meta,\n total, \n }, \n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n query?: Record<string, any>,\n realmId?: string,\n ): Promise<Client> {\n const permissionNames = [\n PermissionName.CLIENT_READ,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n ];\n\n let isMe = !!actor.identity &&\n actor.identity.type === 'client' &&\n (\n actor.identity.data.id === idOrName ||\n actor.identity.data.name === idOrName\n );\n\n if (!isMe) {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n const entity = await this.repository.findOne(idOrName, query, realmId);\n if (!entity) {\n throw new NotFoundError();\n }\n\n if (isMe && actor.identity!.data.id !== entity.id) {\n isMe = false;\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n if (\n !isMe &&\n entity.secret &&\n !entity.secret_encrypted &&\n !entity.secret_hashed\n ) {\n await actor.permissionEvaluator.evaluateOneOf({\n name: permissionNames,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Client> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Client> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Client,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realm_id === 'string' ?\n await this.realmRepository.resolve(data.realm_id) :\n undefined;\n\n let entity: Client | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realm_id = realm.id;\n }\n\n entity = await this.repository.findOneWithSecret(where);\n if (!entity && options.updateOnly) {\n throw new NotFoundError();\n }\n } else if (options.updateOnly) {\n throw new NotFoundError();\n }\n\n let isSelfEdit = false;\n if (entity) {\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_UPDATE });\n } catch (e) {\n if (\n !actor.identity ||\n actor.identity.type !== 'client' ||\n actor.identity.data.id !== entity.id\n ) {\n throw e;\n }\n isSelfEdit = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_SELF_MANAGE });\n }\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n await this.repository.checkUniqueness(validated, entity || undefined);\n\n const credentialsService = new ClientCredentialsService();\n\n if (entity) {\n if (\n !isSelfEdit &&\n !validated.realm_id &&\n !entity.realm_id\n ) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realm_id = actorRealmId;\n }\n }\n\n if (isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_SELF_MANAGE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n }\n\n entity = this.repository.merge(entity, validated);\n\n if (!isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_UPDATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n }\n\n if (entity.is_confidential) {\n if (!validated.secret && !entity.secret) {\n validated.secret = credentialsService.generateSecret();\n }\n\n if (validated.secret) {\n entity.secret = await credentialsService.protect(validated.secret, entity);\n }\n } else {\n entity.secret = null;\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!validated.realm_id) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realm_id = actorRealmId;\n }\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_CREATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n\n entity = this.repository.create(validated);\n\n if (entity.is_confidential) {\n if (!validated.secret) {\n validated.secret = credentialsService.generateSecret();\n }\n\n entity.secret = await credentialsService.protect(validated.secret, validated);\n } else {\n entity.secret = null;\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: true, \n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Client> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.CLIENT_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new NotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.CLIENT_DELETE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":";;;;;;;AA4BA,IAAaS,gBAAb,cAAmCF,sBAAAA;CACrBG;CAEAC;CAEAC;CAEV,YAAYC,KAA2B;AACnC,SAAK;AACL,OAAKH,aAAaG,IAAIH;AACtB,OAAKC,kBAAkBE,IAAIF;AAC3B,OAAKC,YAAY,IAAIR,iBAAAA;;CAGzB,MAAMU,QACFC,OACAC,OAC+C;AAC/C,QAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFd,eAAee;GACff,eAAegB;GACfhB,eAAeiB;GAClB,EACL,CAAA;EAEA,MAAM,EACFC,MAAMC,UACNC,SACA,MAAM,KAAKf,WAAWgB,SAASX,MAAAA;EACnC,IAAI,EAAEY,UAAUF;EAEhB,MAAMF,OAAiB,EAAE;AACzB,OAAK,MAAMK,UAAUJ,UAAU;AAC3B,OACII,OAAOC,UACP,CAACD,OAAOE,oBACR,CAACF,OAAOG,eACV;AACE,QAAI;AACA,WAAMf,MAAMC,oBAAoBe,cAAc;MAC1Cb,MAAM;OACFd,eAAee;OACff,eAAegB;OACfhB,eAAeiB;OAClB;MACDW,OAAO,IAAIhC,WAAW,GAAGD,kBAAkBkC,aAAaN,QAAO,CAAA;MACnE,CAAA;AACAL,UAAKY,KAAKP,OAAAA;YACN;AACJD,cAAS;;AAGb;;AAGJJ,QAAKY,KAAKP,OAAAA;;AAGd,SAAO;GACHL;GACAE,MAAM;IACF,GAAGA;IACHE;IACJ;GACJ;;CAGJ,MAAMS,OACFC,UACArB,OACAD,OACAuB,SACe;EACf,MAAMC,kBAAkB;GACpBlC,eAAee;GACff,eAAegB;GACfhB,eAAeiB;GAClB;EAED,IAAIkB,OAAO,CAAC,CAACxB,MAAMyB,YACfzB,MAAMyB,SAASC,SAAS,aAEpB1B,MAAMyB,SAASlB,KAAKoB,OAAON,YAC3BrB,MAAMyB,SAASlB,KAAKJ,SAASkB;AAGrC,MAAI,CAACG,KACD,OAAMxB,MAAMC,oBAAoBC,iBAAiB,EAAEC,MAAMoB,iBAAgB,CAAA;EAG7E,MAAMX,SAAS,MAAM,KAAKlB,WAAWkC,QAAQP,UAAUtB,OAAOuB,QAAAA;AAC9D,MAAI,CAACV,OACD,OAAM,IAAIzB,eAAAA;AAGd,MAAIqC,QAAQxB,MAAMyB,SAAUlB,KAAKoB,OAAOf,OAAOe,IAAI;AAC/CH,UAAO;AACP,SAAMxB,MAAMC,oBAAoBC,iBAAiB,EAAEC,MAAMoB,iBAAgB,CAAA;;AAG7E,MACI,CAACC,QACDZ,OAAOC,UACP,CAACD,OAAOE,oBACR,CAACF,OAAOG,cAER,OAAMf,MAAMC,oBAAoBe,cAAc;GAC1Cb,MAAMoB;GACNN,OAAO,IAAIhC,WAAW,GAAGD,kBAAkBkC,aAAaN,QAAO,CAAA;GACnE,CAAA;AAGJ,SAAOA;;CAGX,MAAMiB,OACFtB,MACAP,OACe;EACf,MAAM,EAAEY,WAAW,MAAM,KAAKkB,KAAKC,KAAAA,GAAWxB,MAAMP,MAAAA;AACpD,SAAOY;;CAGX,MAAMoB,OACFX,UACAd,MACAP,OACe;EACf,MAAM,EAAEY,WAAW,MAAM,KAAKkB,KAAKT,UAAUd,MAAMP,OAAO,EAAEiC,YAAY,MAAK,CAAA;AAC7E,SAAOrB;;CAGX,MAAMkB,KACFT,UACAd,MACAP,OACAkC,UAAoC,EAAE,EAIvC;EACC,IAAIC;EAEJ,MAAMC,QAAQ,OAAO7B,KAAK8B,aAAa,WACnC,MAAM,KAAK1C,gBAAgB2C,QAAQ/B,KAAK8B,SAAQ,GAChDN,KAAAA;EAEJ,IAAInB;AACJ,MAAIS,UAAU;GACV,MAAMkB,QAA6B,EAAC;AACpC,OAAIrD,OAAOmC,SAAAA,CACPkB,OAAMZ,KAAKN;OAEXkB,OAAMpC,OAAOkB;AAGjB,OAAIe,MACAG,OAAMF,WAAWD,MAAMT;AAG3Bf,YAAS,MAAM,KAAKlB,WAAW8C,kBAAkBD,MAAAA;AACjD,OAAI,CAAC3B,UAAUsB,QAAQD,WACnB,OAAM,IAAI9C,eAAAA;aAEP+C,QAAQD,WACf,OAAM,IAAI9C,eAAAA;EAGd,IAAIsD,aAAa;AACjB,MAAI7B,QAAQ;AACR,OAAI;AACA,UAAMZ,MAAMC,oBAAoByC,YAAY,EAAEvC,MAAMd,eAAegB,eAAc,CAAA;YAC5EsC,GAAG;AACR,QACI,CAAC3C,MAAMyB,YACPzB,MAAMyB,SAASC,SAAS,YACxB1B,MAAMyB,SAASlB,KAAKoB,OAAOf,OAAOe,GAElC,OAAMgB;AAEVF,iBAAa;AACb,UAAMzC,MAAMC,oBAAoByC,YAAY,EAAEvC,MAAMd,eAAeuD,oBAAmB,CAAA;;AAE1FT,WAAQ7C,eAAeuD;SACpB;AACH,SAAM7C,MAAMC,oBAAoByC,YAAY,EAAEvC,MAAMd,eAAeyD,eAAc,CAAA;AACjFX,WAAQ7C,eAAeyD;;EAG3B,MAAMC,YAAY,MAAM,KAAKpD,UAAUqD,IAAI1C,MAAM,EAAE4B,OAAM,CAAA;AAEzD,QAAM,KAAKzC,WAAWwD,oBAAoBF,UAAAA;AAC1C,QAAM,KAAKtD,WAAWyD,gBAAgBH,WAAWpC,UAAUmB,KAAAA,EAAAA;EAE3D,MAAMqB,qBAAqB,IAAI5D,0BAAAA;AAE/B,MAAIoB,QAAQ;AACR,OACI,CAAC6B,cACD,CAACO,UAAUX,YACX,CAACzB,OAAOyB,UACV;IACE,MAAMgB,eAAe,KAAKC,gBAAgBtD,MAAAA;AAC1C,QAAIqD,aACAL,WAAUX,WAAWgB;;AAI7B,OAAIZ,WACA,OAAMzC,MAAMC,oBAAoBsD,SAAS;IACrCpD,MAAMd,eAAeuD;IACrB3B,OAAO,IAAIhC,WAAW,GAAGD,kBAAkBkC,aAAa8B,WAAU,CAAA;IACtE,CAAA;AAGJpC,YAAS,KAAKlB,WAAW8D,MAAM5C,QAAQoC,UAAAA;AAEvC,OAAI,CAACP,WACD,OAAMzC,MAAMC,oBAAoBsD,SAAS;IACrCpD,MAAMd,eAAegB;IACrBY,OAAO,IAAIhC,WAAW,GAAGD,kBAAkBkC,aAAaN,QAAO,CAAA;IACnE,CAAA;AAGJ,OAAIA,OAAO6C,iBAAiB;AACxB,QAAI,CAACT,UAAUnC,UAAU,CAACD,OAAOC,OAC7BmC,WAAUnC,SAASuC,mBAAmBM,gBAAc;AAGxD,QAAIV,UAAUnC,OACVD,QAAOC,SAAS,MAAMuC,mBAAmBO,QAAQX,UAAUnC,QAAQD,OAAAA;SAGvEA,QAAOC,SAAS;AAGpB,SAAM,KAAKnB,WAAWoC,KAAKlB,OAAAA;AAE3B,UAAO;IACHA;IACAgD,SAAS;IACb;;AAGJ,MAAI,CAACZ,UAAUX,UAAU;GACrB,MAAMgB,eAAe,KAAKC,gBAAgBtD,MAAAA;AAC1C,OAAIqD,aACAL,WAAUX,WAAWgB;;AAI7B,QAAMrD,MAAMC,oBAAoBsD,SAAS;GACrCpD,MAAMd,eAAeyD;GACrB7B,OAAO,IAAIhC,WAAW,GAAGD,kBAAkBkC,aAAa8B,WAAU,CAAA;GACtE,CAAA;AAEApC,WAAS,KAAKlB,WAAWmC,OAAOmB,UAAAA;AAEhC,MAAIpC,OAAO6C,iBAAiB;AACxB,OAAI,CAACT,UAAUnC,OACXmC,WAAUnC,SAASuC,mBAAmBM,gBAAc;AAGxD9C,UAAOC,SAAS,MAAMuC,mBAAmBO,QAAQX,UAAUnC,QAAQmC,UAAAA;QAEnEpC,QAAOC,SAAS;AAGpB,QAAM,KAAKnB,WAAWoC,KAAKlB,OAAAA;AAE3B,SAAO;GACHA;GACAgD,SAAS;GACb;;CAGJ,MAAMC,OACFlC,IACA3B,OACe;AACf,QAAMA,MAAMC,oBAAoByC,YAAY,EAAEvC,MAAMd,eAAeiB,eAAc,CAAA;EAEjF,MAAMM,SAAS,MAAM,KAAKlB,WAAWoE,UAAU,EAAEnC,IAAG,CAAA;AACpD,MAAI,CAACf,OACD,OAAM,IAAIzB,eAAAA;AAGd,QAAMa,MAAMC,oBAAoBsD,SAAS;GACrCpD,MAAMd,eAAeiB;GACrBW,OAAO,IAAIhC,WAAW,GAAGD,kBAAkBkC,aAAaN,QAAO,CAAA;GACnE,CAAA;EAEA,MAAM,EAAEe,IAAIoC,aAAanD;AACzB,QAAM,KAAKlB,WAAWsE,OAAOpD,OAAAA;AAC7BA,SAAOe,KAAKoC;AAEZ,SAAOnD"}
|
|
@@ -4,13 +4,14 @@ import type { ActorContext } from '../actor/types.ts';
|
|
|
4
4
|
import type { EntityRepositoryFindManyResult, IEntityRepository } from '../types.ts';
|
|
5
5
|
export interface IClientRepository extends IEntityRepository<Client> {
|
|
6
6
|
checkUniqueness(data: Partial<Client>, existing?: Client): Promise<void>;
|
|
7
|
+
findOne(id: string, query?: Record<string, any>, realm?: string): Promise<Client | null>;
|
|
7
8
|
findOneWithSecret(where: Record<string, any>): Promise<Client | null>;
|
|
8
9
|
getBoundRoles(entity: string | Client): Promise<Role[]>;
|
|
9
10
|
getBoundPermissions(entity: string | Client): Promise<PermissionPolicyBinding[]>;
|
|
10
11
|
}
|
|
11
12
|
export interface IClientService {
|
|
12
13
|
getMany(query: Record<string, any>, actor: ActorContext): Promise<EntityRepositoryFindManyResult<Client>>;
|
|
13
|
-
getOne(idOrName: string, actor: ActorContext, realmId?: string): Promise<Client>;
|
|
14
|
+
getOne(idOrName: string, actor: ActorContext, query?: Record<string, any>, realmId?: string): Promise<Client>;
|
|
14
15
|
create(data: Record<string, any>, actor: ActorContext): Promise<Client>;
|
|
15
16
|
update(idOrName: string, data: Record<string, any>, actor: ActorContext): Promise<Client>;
|
|
16
17
|
save(idOrName: string | undefined, data: Record<string, any>, actor: ActorContext, options?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/client/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErF,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB,CAAC,MAAM,CAAC;IAChE,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEtE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAExD,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1G,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/client/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErF,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB,CAAC,MAAM,CAAC;IAChE,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEzF,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEtE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAExD,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1G,MAAM,CACF,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1F,IAAI,CACA,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC;QACP,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5D"}
|
|
@@ -15,7 +15,7 @@ export declare class RobotService extends AbstractEntityService implements IRobo
|
|
|
15
15
|
protected validator: RobotValidator;
|
|
16
16
|
constructor(ctx: RobotServiceContext);
|
|
17
17
|
getMany(query: Record<string, any>, actor: ActorContext): Promise<EntityRepositoryFindManyResult<Robot>>;
|
|
18
|
-
getOne(idOrName: string, actor: ActorContext, realmId?: string): Promise<Robot>;
|
|
18
|
+
getOne(idOrName: string, actor: ActorContext, query?: Record<string, any>, realmId?: string): Promise<Robot>;
|
|
19
19
|
create(data: Record<string, any>, actor: ActorContext): Promise<Robot>;
|
|
20
20
|
update(idOrName: string, data: Record<string, any>, actor: ActorContext): Promise<Robot>;
|
|
21
21
|
save(idOrName: string | undefined, data: Record<string, any>, actor: ActorContext, options?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/robot/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAEH,cAAc,EAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,MAAM,mBAAmB,GAAG;IAC9B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,eAAe,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,qBAAa,YAAa,SAAQ,qBAAsB,YAAW,aAAa;IAC5E,SAAS,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEvC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC;gBAExB,GAAG,EAAE,mBAAmB;IAO9B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC;IAoD3C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/robot/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAEH,cAAc,EAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,MAAM,mBAAmB,GAAG;IAC9B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,eAAe,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,qBAAa,YAAa,SAAQ,qBAAsB,YAAW,aAAa;IAC5E,SAAS,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEvC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC;gBAExB,GAAG,EAAE,mBAAmB;IAO9B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC;IAoD3C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,KAAK,CAAC;IAsCX,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,KAAK,CAAC;IAKX,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,KAAK,CAAC;IAKX,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,KAAK,CAAC;QACd,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;IAuHI,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,KAAK,CAAC;CA0CpB"}
|
|
@@ -51,28 +51,22 @@ var RobotService = class extends AbstractEntityService {
|
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
async getOne(idOrName, actor, realmId) {
|
|
55
|
-
|
|
54
|
+
async getOne(idOrName, actor, query, realmId) {
|
|
55
|
+
const permissionNames = [
|
|
56
56
|
PermissionName.ROBOT_READ,
|
|
57
57
|
PermissionName.ROBOT_UPDATE,
|
|
58
58
|
PermissionName.ROBOT_DELETE
|
|
59
|
-
]
|
|
60
|
-
let
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
const realm = await this.realmRepository.resolve(realmId);
|
|
64
|
-
entity = realm ? await this.repository.findOneBy({
|
|
65
|
-
name: idOrName,
|
|
66
|
-
realm_id: realm.id
|
|
67
|
-
}) : null;
|
|
68
|
-
} else entity = await this.repository.findOneByName(idOrName);
|
|
59
|
+
];
|
|
60
|
+
let isMe = !!actor.identity && actor.identity.type === "robot" && (actor.identity.data.id === idOrName || actor.identity.data.name === idOrName);
|
|
61
|
+
if (!isMe) await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });
|
|
62
|
+
const entity = await this.repository.findOne(idOrName, query, realmId);
|
|
69
63
|
if (!entity) throw new NotFoundError();
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
64
|
+
if (isMe && actor.identity.data.id !== entity.id) {
|
|
65
|
+
isMe = false;
|
|
66
|
+
await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });
|
|
67
|
+
}
|
|
68
|
+
if (!isMe) await actor.permissionEvaluator.evaluateOneOf({
|
|
69
|
+
name: permissionNames,
|
|
76
70
|
input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity })
|
|
77
71
|
});
|
|
78
72
|
return entity;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PolicyData","isUUID","NotFoundError","PermissionName","RobotValidator","ValidatorGroup","AbstractEntityService","RobotCredentialsService","RobotService","repository","realmRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","ROBOT_READ","ROBOT_UPDATE","ROBOT_DELETE","data","entities","meta","findMany","total","entity","identity","type","id","push","evaluateOneOf","input","ATTRIBUTES","getOne","idOrName","realmId","findOneById","realm","resolve","findOneBy","realm_id","findOneByName","create","save","undefined","update","updateOnly","options","group","where","isSelfEdit","preEvaluate","e","ROBOT_SELF_MANAGE","UPDATE","ROBOT_CREATE","CREATE","validated","run","validateJoinColumns","checkUniqueness","credentialsService","evaluate","merge","secret","protect","created","actorRealmId","getActorRealmId","generateSecret","delete","isOwner","user_id","isSelfDelete","entityId","remove"],"sources":["../../../../src/core/entities/robot/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, PolicyData } from '@authup/access';\nimport { isUUID } from '@authup/kit';\nimport { NotFoundError } from '@ebec/http';\nimport {\n PermissionName,\n RobotValidator,\n ValidatorGroup,\n} from '@authup/core-kit';\nimport type { Robot } from '@authup/core-kit';\nimport type { ActorContext } from '../actor/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '../service.ts';\nimport type { EntityRepositoryFindManyResult } from '../types.ts';\nimport { RobotCredentialsService } from '../../authentication/credential/entities/robot/module.ts';\nimport type { IRobotRepository, IRobotService } from './types.ts';\n\nexport type RobotServiceContext = {\n repository: IRobotRepository;\n realmRepository: IRealmRepository;\n};\n\nexport class RobotService extends AbstractEntityService implements IRobotService {\n protected repository: IRobotRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: RobotValidator;\n\n constructor(ctx: RobotServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new RobotValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Robot>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.ROBOT_READ,\n PermissionName.ROBOT_UPDATE,\n PermissionName.ROBOT_DELETE,\n ],\n });\n\n const {\n data: entities, \n meta, \n } = await this.repository.findMany(query);\n\n const data: Robot[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n if (\n actor.identity &&\n actor.identity.type === 'robot' &&\n actor.identity.data.id === entity.id\n ) {\n data.push(entity);\n continue;\n }\n\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.ROBOT_READ,\n PermissionName.ROBOT_UPDATE,\n PermissionName.ROBOT_DELETE,\n ],\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total, \n }, \n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Robot> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.ROBOT_READ,\n PermissionName.ROBOT_UPDATE,\n PermissionName.ROBOT_DELETE,\n ],\n });\n\n let entity: Robot | null;\n if (isUUID(idOrName)) {\n entity = await this.repository.findOneById(idOrName);\n } else if (realmId) {\n const realm = await this.realmRepository.resolve(realmId);\n entity = realm ?\n await this.repository.findOneBy({\n name: idOrName,\n realm_id: realm.id, \n }) :\n null;\n } else {\n entity = await this.repository.findOneByName(idOrName);\n }\n\n if (!entity) {\n throw new NotFoundError();\n }\n\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.ROBOT_READ,\n PermissionName.ROBOT_UPDATE,\n PermissionName.ROBOT_DELETE,\n ],\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Robot> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Robot> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Robot,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realm_id === 'string' ?\n await this.realmRepository.resolve(data.realm_id) :\n undefined;\n\n let entity: Robot | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realm_id = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n if (!entity && options.updateOnly) {\n throw new NotFoundError();\n }\n } else if (options.updateOnly) {\n throw new NotFoundError();\n }\n\n let isSelfEdit = false;\n if (entity) {\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_UPDATE });\n } catch (e) {\n if (\n !actor.identity ||\n actor.identity.type !== 'robot' ||\n actor.identity.data.id !== entity.id\n ) {\n throw e;\n }\n isSelfEdit = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_SELF_MANAGE });\n }\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n await this.repository.checkUniqueness(validated, entity || undefined);\n\n const credentialsService = new RobotCredentialsService();\n\n if (entity) {\n if (isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_SELF_MANAGE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n } else {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_UPDATE,\n input: new PolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n }),\n });\n }\n\n entity = this.repository.merge(entity, validated);\n if (validated.secret) {\n entity.secret = await credentialsService.protect(validated.secret);\n }\n\n await this.repository.save(entity);\n\n if (validated.secret) {\n entity.secret = validated.secret;\n }\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!validated.realm_id) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realm_id = actorRealmId;\n }\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_CREATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n\n if (!validated.secret) {\n validated.secret = credentialsService.generateSecret();\n }\n\n entity = this.repository.create(validated);\n entity.secret = await credentialsService.protect(validated.secret);\n await this.repository.save(entity);\n entity.secret = validated.secret;\n\n return {\n entity,\n created: true, \n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Robot> {\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new NotFoundError();\n }\n\n const isOwner = entity.user_id &&\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === entity.user_id;\n\n let isSelfDelete = false;\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_DELETE });\n } catch (e) {\n if (!isOwner) {\n throw e;\n }\n isSelfDelete = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_SELF_MANAGE });\n }\n\n if (isSelfDelete) {\n // Delete carries no attributes to validate; pass an empty input so\n // the ATTRIBUTE_NAMES denylist has no keys to reject.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_SELF_MANAGE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: {} }),\n });\n } else {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_DELETE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n }\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PolicyData","isUUID","NotFoundError","PermissionName","RobotValidator","ValidatorGroup","AbstractEntityService","RobotCredentialsService","RobotService","repository","realmRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","ROBOT_READ","ROBOT_UPDATE","ROBOT_DELETE","data","entities","meta","findMany","total","entity","identity","type","id","push","evaluateOneOf","input","ATTRIBUTES","getOne","idOrName","realmId","permissionNames","isMe","findOne","create","save","undefined","update","updateOnly","options","group","realm","realm_id","resolve","where","findOneBy","isSelfEdit","preEvaluate","e","ROBOT_SELF_MANAGE","UPDATE","ROBOT_CREATE","CREATE","validated","run","validateJoinColumns","checkUniqueness","credentialsService","evaluate","merge","secret","protect","created","actorRealmId","getActorRealmId","generateSecret","delete","isOwner","user_id","isSelfDelete","entityId","remove"],"sources":["../../../../src/core/entities/robot/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, PolicyData } from '@authup/access';\nimport { isUUID } from '@authup/kit';\nimport { NotFoundError } from '@ebec/http';\nimport {\n PermissionName,\n RobotValidator,\n ValidatorGroup,\n} from '@authup/core-kit';\nimport type { Robot } from '@authup/core-kit';\nimport type { ActorContext } from '../actor/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '../service.ts';\nimport type { EntityRepositoryFindManyResult } from '../types.ts';\nimport { RobotCredentialsService } from '../../authentication/credential/entities/robot/module.ts';\nimport type { IRobotRepository, IRobotService } from './types.ts';\n\nexport type RobotServiceContext = {\n repository: IRobotRepository;\n realmRepository: IRealmRepository;\n};\n\nexport class RobotService extends AbstractEntityService implements IRobotService {\n protected repository: IRobotRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: RobotValidator;\n\n constructor(ctx: RobotServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new RobotValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Robot>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.ROBOT_READ,\n PermissionName.ROBOT_UPDATE,\n PermissionName.ROBOT_DELETE,\n ],\n });\n\n const {\n data: entities, \n meta, \n } = await this.repository.findMany(query);\n\n const data: Robot[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n if (\n actor.identity &&\n actor.identity.type === 'robot' &&\n actor.identity.data.id === entity.id\n ) {\n data.push(entity);\n continue;\n }\n\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.ROBOT_READ,\n PermissionName.ROBOT_UPDATE,\n PermissionName.ROBOT_DELETE,\n ],\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total, \n }, \n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n query?: Record<string, any>,\n realmId?: string,\n ): Promise<Robot> {\n const permissionNames = [\n PermissionName.ROBOT_READ,\n PermissionName.ROBOT_UPDATE,\n PermissionName.ROBOT_DELETE,\n ];\n\n let isMe = !!actor.identity &&\n actor.identity.type === 'robot' &&\n (\n actor.identity.data.id === idOrName ||\n actor.identity.data.name === idOrName\n );\n\n if (!isMe) {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n const entity = await this.repository.findOne(idOrName, query, realmId);\n if (!entity) {\n throw new NotFoundError();\n }\n\n if (isMe && actor.identity!.data.id !== entity.id) {\n isMe = false;\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n if (!isMe) {\n await actor.permissionEvaluator.evaluateOneOf({\n name: permissionNames,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Robot> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Robot> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Robot,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realm_id === 'string' ?\n await this.realmRepository.resolve(data.realm_id) :\n undefined;\n\n let entity: Robot | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realm_id = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n if (!entity && options.updateOnly) {\n throw new NotFoundError();\n }\n } else if (options.updateOnly) {\n throw new NotFoundError();\n }\n\n let isSelfEdit = false;\n if (entity) {\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_UPDATE });\n } catch (e) {\n if (\n !actor.identity ||\n actor.identity.type !== 'robot' ||\n actor.identity.data.id !== entity.id\n ) {\n throw e;\n }\n isSelfEdit = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_SELF_MANAGE });\n }\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n await this.repository.checkUniqueness(validated, entity || undefined);\n\n const credentialsService = new RobotCredentialsService();\n\n if (entity) {\n if (isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_SELF_MANAGE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n } else {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_UPDATE,\n input: new PolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n }),\n });\n }\n\n entity = this.repository.merge(entity, validated);\n if (validated.secret) {\n entity.secret = await credentialsService.protect(validated.secret);\n }\n\n await this.repository.save(entity);\n\n if (validated.secret) {\n entity.secret = validated.secret;\n }\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!validated.realm_id) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realm_id = actorRealmId;\n }\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_CREATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n\n if (!validated.secret) {\n validated.secret = credentialsService.generateSecret();\n }\n\n entity = this.repository.create(validated);\n entity.secret = await credentialsService.protect(validated.secret);\n await this.repository.save(entity);\n entity.secret = validated.secret;\n\n return {\n entity,\n created: true, \n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Robot> {\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new NotFoundError();\n }\n\n const isOwner = entity.user_id &&\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === entity.user_id;\n\n let isSelfDelete = false;\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_DELETE });\n } catch (e) {\n if (!isOwner) {\n throw e;\n }\n isSelfDelete = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.ROBOT_SELF_MANAGE });\n }\n\n if (isSelfDelete) {\n // Delete carries no attributes to validate; pass an empty input so\n // the ATTRIBUTE_NAMES denylist has no keys to reject.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_SELF_MANAGE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: {} }),\n });\n } else {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.ROBOT_DELETE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n }\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
|
|
@@ -4,13 +4,14 @@ import type { ActorContext } from '../actor/types.ts';
|
|
|
4
4
|
import type { EntityRepositoryFindManyResult, IEntityRepository } from '../types.ts';
|
|
5
5
|
export interface IRobotRepository extends IEntityRepository<Robot> {
|
|
6
6
|
checkUniqueness(data: Partial<Robot>, existing?: Robot): Promise<void>;
|
|
7
|
+
findOne(id: string, query?: Record<string, any>, realm?: string): Promise<Robot | null>;
|
|
7
8
|
findOneWithSecret(where: Record<string, any>): Promise<Robot | null>;
|
|
8
9
|
getBoundRoles(entity: string | Robot): Promise<Role[]>;
|
|
9
10
|
getBoundPermissions(entity: string | Robot): Promise<PermissionPolicyBinding[]>;
|
|
10
11
|
}
|
|
11
12
|
export interface IRobotService {
|
|
12
13
|
getMany(query: Record<string, any>, actor: ActorContext): Promise<EntityRepositoryFindManyResult<Robot>>;
|
|
13
|
-
getOne(idOrName: string, actor: ActorContext, realmId?: string): Promise<Robot>;
|
|
14
|
+
getOne(idOrName: string, actor: ActorContext, query?: Record<string, any>, realmId?: string): Promise<Robot>;
|
|
14
15
|
create(data: Record<string, any>, actor: ActorContext): Promise<Robot>;
|
|
15
16
|
update(idOrName: string, data: Record<string, any>, actor: ActorContext): Promise<Robot>;
|
|
16
17
|
save(idOrName: string | undefined, data: Record<string, any>, actor: ActorContext, options?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/robot/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErF,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB,CAAC,KAAK,CAAC;IAC9D,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvE,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAErE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAEvD,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;CACnF;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC,CAAC;IACzG,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/robot/types.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErF,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB,CAAC,KAAK,CAAC;IAC9D,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAExF,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAErE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAEvD,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;CACnF;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC,CAAC;IACzG,MAAM,CACF,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,KAAK,CAAC,CAAC;IAClB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACzF,IAAI,CACA,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC;QACP,MAAM,EAAE,KAAK,CAAC;QACd,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;CAC3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/user/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAEH,aAAa,EAEhB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,MAAM,kBAAkB,GAAG;IAC7B,UAAU,EAAE,eAAe,CAAC;IAC5B,eAAe,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,qBAAa,WAAY,SAAQ,qBAAsB,YAAW,YAAY;IAC1E,SAAS,CAAC,UAAU,EAAE,eAAe,CAAC;IAEtC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC;gBAEvB,GAAG,EAAE,kBAAkB;IAO7B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;IAoD1C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/user/service.ts"],"names":[],"mappings":"AAUA,OAAO,EAEH,aAAa,EAEhB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,MAAM,kBAAkB,GAAG;IAC7B,UAAU,EAAE,eAAe,CAAC;IAC5B,eAAe,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,qBAAa,WAAY,SAAQ,qBAAsB,YAAW,YAAY;IAC1E,SAAS,CAAC,UAAU,EAAE,eAAe,CAAC;IAEtC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC;gBAEvB,GAAG,EAAE,kBAAkB;IAO7B,OAAO,CACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;IAoD1C,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAsCV,MAAM,CACR,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,MAAM,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAKV,IAAI,CACN,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC,OAAO,CAAC;QACP,MAAM,EAAE,IAAI,CAAC;QACb,OAAO,EAAE,OAAO,CAAA;KACnB,CAAC;IAqII,MAAM,CACR,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;CA2BnB"}
|
|
@@ -52,24 +52,21 @@ var UserService = class extends AbstractEntityService {
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
async getOne(idOrName, actor, query, realmId) {
|
|
55
|
-
|
|
56
|
-
if (actor.identity && actor.identity.type === "user") {
|
|
57
|
-
if (actor.identity.data.id === idOrName || actor.identity.data.name === idOrName) isMe = true;
|
|
58
|
-
}
|
|
59
|
-
if (!isMe) await actor.permissionEvaluator.preEvaluateOneOf({ name: [
|
|
55
|
+
const permissionNames = [
|
|
60
56
|
PermissionName.USER_READ,
|
|
61
57
|
PermissionName.USER_UPDATE,
|
|
62
58
|
PermissionName.USER_DELETE
|
|
63
|
-
]
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
];
|
|
60
|
+
let isMe = !!actor.identity && actor.identity.type === "user" && (actor.identity.data.id === idOrName || actor.identity.data.name === idOrName);
|
|
61
|
+
if (!isMe) await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });
|
|
62
|
+
const entity = await this.repository.findOne(idOrName, query, realmId);
|
|
66
63
|
if (!entity) throw new NotFoundError();
|
|
64
|
+
if (isMe && actor.identity.data.id !== entity.id) {
|
|
65
|
+
isMe = false;
|
|
66
|
+
await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });
|
|
67
|
+
}
|
|
67
68
|
if (!isMe) await actor.permissionEvaluator.evaluateOneOf({
|
|
68
|
-
name:
|
|
69
|
-
PermissionName.USER_READ,
|
|
70
|
-
PermissionName.USER_UPDATE,
|
|
71
|
-
PermissionName.USER_DELETE
|
|
72
|
-
],
|
|
69
|
+
name: permissionNames,
|
|
73
70
|
input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity })
|
|
74
71
|
});
|
|
75
72
|
return entity;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PolicyData","isUUID","BadRequestError","NotFoundError","PermissionName","UserValidator","ValidatorGroup","AbstractEntityService","UserCredentialsService","UserService","repository","realmRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","USER_READ","USER_UPDATE","USER_DELETE","data","entities","meta","findMany","total","entity","identity","type","id","push","evaluateOneOf","input","ATTRIBUTES","getOne","idOrName","realmId","isMe","resolvedId","findOne","create","save","undefined","update","updateOnly","options","group","realm","realm_id","resolve","where","findOneBy","isSelfEdit","preEvaluate","e","USER_SELF_MANAGE","UPDATE","USER_CREATE","CREATE","validated","run","validateJoinColumns","credentialsService","originalName","originalNameLocked","name_locked","evaluate","merge","password","protect","created","actorRealmId","getActorRealmId","delete","entityId","remove"],"sources":["../../../../src/core/entities/user/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, PolicyData } from '@authup/access';\nimport { isUUID } from '@authup/kit';\nimport { BadRequestError, NotFoundError } from '@ebec/http';\nimport {\n PermissionName,\n UserValidator,\n ValidatorGroup,\n} from '@authup/core-kit';\nimport type { User } from '@authup/core-kit';\nimport type { ActorContext } from '../actor/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '../service.ts';\nimport type { EntityRepositoryFindManyResult } from '../types.ts';\nimport { UserCredentialsService } from '../../authentication/credential/entities/user/module.ts';\nimport type { IUserRepository, IUserService } from './types.ts';\n\nexport type UserServiceContext = {\n repository: IUserRepository;\n realmRepository: IRealmRepository;\n};\n\nexport class UserService extends AbstractEntityService implements IUserService {\n protected repository: IUserRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: UserValidator;\n\n constructor(ctx: UserServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new UserValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<User>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ],\n });\n\n const {\n data: entities, \n meta, \n } = await this.repository.findMany(query);\n\n const data: User[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n if (\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === entity.id\n ) {\n data.push(entity);\n continue;\n }\n\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ],\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total, \n }, \n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n query?: Record<string, any>,\n realmId?: string,\n ): Promise<User> {\n let isMe = false;\n if (actor.identity && actor.identity.type === 'user') {\n if (\n actor.identity.data.id === idOrName ||\n actor.identity.data.name === idOrName\n ) {\n isMe = true;\n }\n }\n\n if (!isMe) {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ],\n });\n }\n\n const resolvedId = isMe ? actor.identity!.data.id : idOrName;\n const entity = await this.repository.findOne(resolvedId, query, realmId);\n if (!entity) {\n throw new NotFoundError();\n }\n\n if (!isMe) {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ],\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<User> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<User> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: User,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realm_id === 'string' ?\n await this.realmRepository.resolve(data.realm_id) :\n undefined;\n\n let entity: User | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realm_id = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n if (!entity && options.updateOnly) {\n throw new NotFoundError();\n }\n } else if (options.updateOnly) {\n throw new NotFoundError();\n }\n\n let isSelfEdit = false;\n if (entity) {\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_UPDATE });\n } catch (e) {\n if (\n !actor.identity ||\n actor.identity.type !== 'user' ||\n actor.identity.data.id !== entity.id\n ) {\n throw e;\n }\n isSelfEdit = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_SELF_MANAGE });\n }\n\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_CREATE });\n\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n const credentialsService = new UserCredentialsService();\n\n if (entity) {\n const originalName = entity.name;\n const originalNameLocked = entity.name_locked;\n\n if (isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_SELF_MANAGE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n }\n\n entity = this.repository.merge(entity, validated);\n\n if (\n validated.name &&\n validated.name !== originalName\n ) {\n if (validated.name_locked) {\n entity.name_locked = validated.name_locked;\n }\n\n if (originalNameLocked && validated.name_locked !== false) {\n entity.name = originalName;\n }\n }\n\n if (!isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_UPDATE,\n input: new PolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n }),\n });\n }\n\n if (validated.password) {\n entity.password = await credentialsService.protect(validated.password);\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!validated.realm_id) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realm_id = actorRealmId;\n }\n }\n\n entity = this.repository.create(validated);\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_CREATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n if (validated.password) {\n entity.password = await credentialsService.protect(validated.password);\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: true, \n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<User> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_DELETE });\n\n if (\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === id\n ) {\n throw new BadRequestError('The own user can not be deleted.');\n }\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new NotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_DELETE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PolicyData","isUUID","BadRequestError","NotFoundError","PermissionName","UserValidator","ValidatorGroup","AbstractEntityService","UserCredentialsService","UserService","repository","realmRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","USER_READ","USER_UPDATE","USER_DELETE","data","entities","meta","findMany","total","entity","identity","type","id","push","evaluateOneOf","input","ATTRIBUTES","getOne","idOrName","realmId","permissionNames","isMe","findOne","create","save","undefined","update","updateOnly","options","group","realm","realm_id","resolve","where","findOneBy","isSelfEdit","preEvaluate","e","USER_SELF_MANAGE","UPDATE","USER_CREATE","CREATE","validated","run","validateJoinColumns","credentialsService","originalName","originalNameLocked","name_locked","evaluate","merge","password","protect","created","actorRealmId","getActorRealmId","delete","entityId","remove"],"sources":["../../../../src/core/entities/user/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, PolicyData } from '@authup/access';\nimport { isUUID } from '@authup/kit';\nimport { BadRequestError, NotFoundError } from '@ebec/http';\nimport {\n PermissionName,\n UserValidator,\n ValidatorGroup,\n} from '@authup/core-kit';\nimport type { User } from '@authup/core-kit';\nimport type { ActorContext } from '../actor/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport { AbstractEntityService } from '../service.ts';\nimport type { EntityRepositoryFindManyResult } from '../types.ts';\nimport { UserCredentialsService } from '../../authentication/credential/entities/user/module.ts';\nimport type { IUserRepository, IUserService } from './types.ts';\n\nexport type UserServiceContext = {\n repository: IUserRepository;\n realmRepository: IRealmRepository;\n};\n\nexport class UserService extends AbstractEntityService implements IUserService {\n protected repository: IUserRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected validator: UserValidator;\n\n constructor(ctx: UserServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.validator = new UserValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<User>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ],\n });\n\n const {\n data: entities, \n meta, \n } = await this.repository.findMany(query);\n\n const data: User[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n if (\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === entity.id\n ) {\n data.push(entity);\n continue;\n }\n\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ],\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total, \n }, \n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n query?: Record<string, any>,\n realmId?: string,\n ): Promise<User> {\n const permissionNames = [\n PermissionName.USER_READ,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n ];\n\n let isMe = !!actor.identity &&\n actor.identity.type === 'user' &&\n (\n actor.identity.data.id === idOrName ||\n actor.identity.data.name === idOrName\n );\n\n if (!isMe) {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n const entity = await this.repository.findOne(idOrName, query, realmId);\n if (!entity) {\n throw new NotFoundError();\n }\n\n if (isMe && actor.identity!.data.id !== entity.id) {\n isMe = false;\n await actor.permissionEvaluator.preEvaluateOneOf({ name: permissionNames });\n }\n\n if (!isMe) {\n await actor.permissionEvaluator.evaluateOneOf({\n name: permissionNames,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<User> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<User> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: User,\n created: boolean \n }> {\n let group: string;\n\n const realm = typeof data.realm_id === 'string' ?\n await this.realmRepository.resolve(data.realm_id) :\n undefined;\n\n let entity: User | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realm_id = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n if (!entity && options.updateOnly) {\n throw new NotFoundError();\n }\n } else if (options.updateOnly) {\n throw new NotFoundError();\n }\n\n let isSelfEdit = false;\n if (entity) {\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_UPDATE });\n } catch (e) {\n if (\n !actor.identity ||\n actor.identity.type !== 'user' ||\n actor.identity.data.id !== entity.id\n ) {\n throw e;\n }\n isSelfEdit = true;\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_SELF_MANAGE });\n }\n\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_CREATE });\n\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n const credentialsService = new UserCredentialsService();\n\n if (entity) {\n const originalName = entity.name;\n const originalNameLocked = entity.name_locked;\n\n if (isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_SELF_MANAGE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated }),\n });\n }\n\n entity = this.repository.merge(entity, validated);\n\n if (\n validated.name &&\n validated.name !== originalName\n ) {\n if (validated.name_locked) {\n entity.name_locked = validated.name_locked;\n }\n\n if (originalNameLocked && validated.name_locked !== false) {\n entity.name = originalName;\n }\n }\n\n if (!isSelfEdit) {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_UPDATE,\n input: new PolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n }),\n });\n }\n\n if (validated.password) {\n entity.password = await credentialsService.protect(validated.password);\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: false, \n };\n }\n\n if (!validated.realm_id) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realm_id = actorRealmId;\n }\n }\n\n entity = this.repository.create(validated);\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_CREATE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n if (validated.password) {\n entity.password = await credentialsService.protect(validated.password);\n }\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: true, \n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<User> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.USER_DELETE });\n\n if (\n actor.identity &&\n actor.identity.type === 'user' &&\n actor.identity.data.id === id\n ) {\n throw new BadRequestError('The own user can not be deleted.');\n }\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new NotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.USER_DELETE,\n input: new PolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/identity/password-recovery/service.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACR,wBAAwB,EACxB,oBAAoB,EACpB,8BAA8B,EAC9B,8BAA8B,EAC9B,mBAAmB,EACtB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEjF,qBAAa,uBAAwB,YAAW,wBAAwB;IACpE,SAAS,CAAC,OAAO,EAAE,8BAA8B,CAAC;IAElD,SAAS,CAAC,UAAU,EAAE,eAAe,CAAC;IAEtC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,UAAU,EAAE,WAAW,CAAC;gBAEtB,GAAG,EAAE,8BAA8B;IAOzC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAsDxE,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC;YA0C9D,0BAA0B;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/core/identity/password-recovery/service.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACR,wBAAwB,EACxB,oBAAoB,EACpB,8BAA8B,EAC9B,8BAA8B,EAC9B,mBAAmB,EACtB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEjF,qBAAa,uBAAwB,YAAW,wBAAwB;IACpE,SAAS,CAAC,OAAO,EAAE,8BAA8B,CAAC;IAElD,SAAS,CAAC,UAAU,EAAE,eAAe,CAAC;IAEtC,SAAS,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAE5C,SAAS,CAAC,UAAU,EAAE,WAAW,CAAC;gBAEtB,GAAG,EAAE,8BAA8B;IAOzC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAsDxE,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC;YA0C9D,0BAA0B;YA8C1B,yBAAyB;CA2E1C"}
|
|
@@ -79,10 +79,10 @@ var PasswordRecoveryService = class {
|
|
|
79
79
|
const validator = new Container({});
|
|
80
80
|
const oneOfContainer = new Container({ oneOf: true });
|
|
81
81
|
oneOfContainer.mount("email", createValidator(() => {
|
|
82
|
-
return createValidationChain().exists().notEmpty().isEmail();
|
|
82
|
+
return createValidationChain().exists().notEmpty().trim().toLowerCase().isEmail().matches(/^[^A-Z]+$/).withMessage("Email must be lowercase.");
|
|
83
83
|
}));
|
|
84
84
|
oneOfContainer.mount("name", createValidator(() => {
|
|
85
|
-
return createValidationChain().exists().notEmpty().isString();
|
|
85
|
+
return createValidationChain().exists().notEmpty().isString().trim().toLowerCase();
|
|
86
86
|
}));
|
|
87
87
|
validator.mount(oneOfContainer);
|
|
88
88
|
validator.mount("realm_id", { optional: true }, createValidator(() => {
|
|
@@ -94,10 +94,10 @@ var PasswordRecoveryService = class {
|
|
|
94
94
|
const validator = new Container({});
|
|
95
95
|
const oneOfContainer = new Container({ oneOf: true });
|
|
96
96
|
oneOfContainer.mount("email", createValidator(() => {
|
|
97
|
-
return createValidationChain().exists().notEmpty().isEmail();
|
|
97
|
+
return createValidationChain().exists().notEmpty().trim().toLowerCase().isEmail().matches(/^[^A-Z]+$/).withMessage("Email must be lowercase.");
|
|
98
98
|
}));
|
|
99
99
|
oneOfContainer.mount("name", createValidator(() => {
|
|
100
|
-
return createValidationChain().exists().notEmpty().isString();
|
|
100
|
+
return createValidationChain().exists().notEmpty().isString().trim().toLowerCase();
|
|
101
101
|
}));
|
|
102
102
|
validator.mount(oneOfContainer);
|
|
103
103
|
validator.mount("realm_id", { optional: true }, createValidator(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":["BadRequestError","NotFoundError","createValidationChain","createValidator","randomBytes","Container","UserCredentialsService","PasswordRecoveryService","options","repository","realmRepository","mailClient","ctx","forgotPassword","data","passwordRecoveryEnabled","emailVerificationEnabled","validated","runForgotPasswordValidator","realm","resolve","realm_id","where","name","email","id","entity","findOneByWithEmail","merged","merge","reset_expires","Date","now","toISOString","reset_hash","toString","save","send","to","subject","html","resetPassword","runResetPasswordValidator","validateJoinColumns","token","findOneBy","credentialsService","hashedPassword","protect","password","reset_at","validator","oneOfContainer","oneOf","mount","chain","exists","notEmpty","isEmail","isString","optional","isUUID","values","run","isLength","min","max"],"sources":["../../../../src/core/identity/password-recovery/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BadRequestError, NotFoundError } from '@ebec/http';\nimport { createValidationChain, createValidator } from '@validup/adapter-validator';\nimport { randomBytes } from 'node:crypto';\nimport { Container } from 'validup';\nimport { UserCredentialsService } from '../../authentication/credential/entities/user/module.ts';\nimport type {\n IPasswordRecoveryService,\n PasswordForgotResult,\n PasswordRecoveryServiceContext,\n PasswordRecoveryServiceOptions,\n PasswordResetResult,\n} from './types.ts';\nimport type { IMailClient } from '../../mail/types.ts';\nimport type { IRealmRepository, IUserRepository } from '../../entities/index.ts';\n\nexport class PasswordRecoveryService implements IPasswordRecoveryService {\n protected options: PasswordRecoveryServiceOptions;\n\n protected repository: IUserRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected mailClient: IMailClient;\n\n constructor(ctx: PasswordRecoveryServiceContext) {\n this.options = ctx.options;\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.mailClient = ctx.mailClient;\n }\n\n async forgotPassword(data: Record<string, any>): Promise<PasswordForgotResult> {\n if (!this.options.passwordRecoveryEnabled) {\n throw new BadRequestError('Password recovery is not enabled.');\n }\n\n if (!this.options.emailVerificationEnabled) {\n throw new BadRequestError('Email verification is not enabled, but required to reset a password.');\n }\n\n const validated = await this.runForgotPasswordValidator(data);\n\n const realm = await this.realmRepository.resolve(validated.realm_id, true);\n\n const where: Record<string, any> = {\n ...(validated.name ? { name: validated.name } : {}),\n ...(validated.email ? { email: validated.email } : {}),\n realm_id: realm.id,\n };\n\n const entity = await this.repository.findOneByWithEmail(where);\n\n if (!entity) {\n throw new NotFoundError();\n }\n\n const merged = this.repository.merge(entity, {\n reset_expires: new Date(Date.now() + (1000 * 60 * 30)).toISOString(),\n reset_hash: randomBytes(32).toString('hex'),\n });\n\n await this.repository.save(merged);\n\n try {\n await this.mailClient.send({\n to: entity.email,\n subject: 'Forgot Password - Reset code',\n html: `\n <p>Please use the code below to reset your account password.</p>\n <p>${merged.reset_hash}</p>\n `,\n });\n } catch {\n this.repository.merge(merged, {\n reset_hash: null,\n reset_expires: null,\n });\n await this.repository.save(merged);\n\n throw new BadRequestError('Password recovery failed. Could not send reset email.');\n }\n\n return { reset_expires: merged.reset_expires! };\n }\n\n async resetPassword(data: Record<string, any>): Promise<PasswordResetResult> {\n if (!this.options.passwordRecoveryEnabled) {\n throw new BadRequestError('Password recovery is not enabled.');\n }\n\n const validated = await this.runResetPasswordValidator(data);\n\n await this.repository.validateJoinColumns(validated);\n\n const realm = await this.realmRepository.resolve(validated.realm_id, true);\n\n const where: Record<string, any> = {\n ...(validated.name ? { name: validated.name } : {}),\n ...(validated.email ? { email: validated.email } : {}),\n reset_hash: validated.token,\n realm_id: realm.id,\n };\n\n const entity = await this.repository.findOneBy(where);\n if (!entity) {\n throw new NotFoundError();\n }\n\n if (!entity.reset_expires || new Date(entity.reset_expires) < new Date()) {\n throw new BadRequestError('Reset token has expired.');\n }\n\n const credentialsService = new UserCredentialsService();\n const hashedPassword = await credentialsService.protect(validated.password);\n\n const merged = this.repository.merge(entity, {\n reset_at: new Date().toISOString(),\n reset_hash: null,\n reset_expires: null,\n password: hashedPassword,\n });\n\n await this.repository.save(merged);\n\n return { reset_at: merged.reset_at! };\n }\n\n private async runForgotPasswordValidator(data: Record<string, any>) {\n const validator = new Container<any>({});\n\n const oneOfContainer = new Container({ oneOf: true });\n\n oneOfContainer.mount('email', createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isEmail();\n }));\n\n oneOfContainer.mount(\n 'name',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isString();\n }),\n );\n\n validator.mount(oneOfContainer);\n\n validator.mount(\n 'realm_id',\n { optional: true },\n createValidator(() => {\n const chain = createValidationChain();\n return chain.exists()\n .isUUID()\n .optional({ values: 'null' });\n }),\n );\n\n return validator.run(data);\n }\n\n private async runResetPasswordValidator(data: Record<string, any>) {\n const validator = new Container<any>({});\n\n const oneOfContainer = new Container({ oneOf: true });\n oneOfContainer.mount(\n 'email',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isEmail();\n }),\n );\n oneOfContainer.mount(\n 'name',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isString();\n }),\n );\n\n validator.mount(oneOfContainer);\n\n validator.mount(\n 'realm_id',\n { optional: true },\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .isUUID()\n .optional({ values: 'null' });\n }),\n );\n\n validator.mount(\n 'token',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isLength({\n min: 3,\n max: 256, \n });\n }),\n );\n\n validator.mount(\n 'password',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isLength({\n min: 5,\n max: 512, \n });\n }),\n );\n\n return validator.run(data);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["BadRequestError","NotFoundError","createValidationChain","createValidator","randomBytes","Container","UserCredentialsService","PasswordRecoveryService","options","repository","realmRepository","mailClient","ctx","forgotPassword","data","passwordRecoveryEnabled","emailVerificationEnabled","validated","runForgotPasswordValidator","realm","resolve","realm_id","where","name","email","id","entity","findOneByWithEmail","merged","merge","reset_expires","Date","now","toISOString","reset_hash","toString","save","send","to","subject","html","resetPassword","runResetPasswordValidator","validateJoinColumns","token","findOneBy","credentialsService","hashedPassword","protect","password","reset_at","validator","oneOfContainer","oneOf","mount","chain","exists","notEmpty","trim","toLowerCase","isEmail","matches","withMessage","isString","optional","isUUID","values","run","isLength","min","max"],"sources":["../../../../src/core/identity/password-recovery/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BadRequestError, NotFoundError } from '@ebec/http';\nimport { createValidationChain, createValidator } from '@validup/adapter-validator';\nimport { randomBytes } from 'node:crypto';\nimport { Container } from 'validup';\nimport { UserCredentialsService } from '../../authentication/credential/entities/user/module.ts';\nimport type {\n IPasswordRecoveryService,\n PasswordForgotResult,\n PasswordRecoveryServiceContext,\n PasswordRecoveryServiceOptions,\n PasswordResetResult,\n} from './types.ts';\nimport type { IMailClient } from '../../mail/types.ts';\nimport type { IRealmRepository, IUserRepository } from '../../entities/index.ts';\n\nexport class PasswordRecoveryService implements IPasswordRecoveryService {\n protected options: PasswordRecoveryServiceOptions;\n\n protected repository: IUserRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected mailClient: IMailClient;\n\n constructor(ctx: PasswordRecoveryServiceContext) {\n this.options = ctx.options;\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.mailClient = ctx.mailClient;\n }\n\n async forgotPassword(data: Record<string, any>): Promise<PasswordForgotResult> {\n if (!this.options.passwordRecoveryEnabled) {\n throw new BadRequestError('Password recovery is not enabled.');\n }\n\n if (!this.options.emailVerificationEnabled) {\n throw new BadRequestError('Email verification is not enabled, but required to reset a password.');\n }\n\n const validated = await this.runForgotPasswordValidator(data);\n\n const realm = await this.realmRepository.resolve(validated.realm_id, true);\n\n const where: Record<string, any> = {\n ...(validated.name ? { name: validated.name } : {}),\n ...(validated.email ? { email: validated.email } : {}),\n realm_id: realm.id,\n };\n\n const entity = await this.repository.findOneByWithEmail(where);\n\n if (!entity) {\n throw new NotFoundError();\n }\n\n const merged = this.repository.merge(entity, {\n reset_expires: new Date(Date.now() + (1000 * 60 * 30)).toISOString(),\n reset_hash: randomBytes(32).toString('hex'),\n });\n\n await this.repository.save(merged);\n\n try {\n await this.mailClient.send({\n to: entity.email,\n subject: 'Forgot Password - Reset code',\n html: `\n <p>Please use the code below to reset your account password.</p>\n <p>${merged.reset_hash}</p>\n `,\n });\n } catch {\n this.repository.merge(merged, {\n reset_hash: null,\n reset_expires: null,\n });\n await this.repository.save(merged);\n\n throw new BadRequestError('Password recovery failed. Could not send reset email.');\n }\n\n return { reset_expires: merged.reset_expires! };\n }\n\n async resetPassword(data: Record<string, any>): Promise<PasswordResetResult> {\n if (!this.options.passwordRecoveryEnabled) {\n throw new BadRequestError('Password recovery is not enabled.');\n }\n\n const validated = await this.runResetPasswordValidator(data);\n\n await this.repository.validateJoinColumns(validated);\n\n const realm = await this.realmRepository.resolve(validated.realm_id, true);\n\n const where: Record<string, any> = {\n ...(validated.name ? { name: validated.name } : {}),\n ...(validated.email ? { email: validated.email } : {}),\n reset_hash: validated.token,\n realm_id: realm.id,\n };\n\n const entity = await this.repository.findOneBy(where);\n if (!entity) {\n throw new NotFoundError();\n }\n\n if (!entity.reset_expires || new Date(entity.reset_expires) < new Date()) {\n throw new BadRequestError('Reset token has expired.');\n }\n\n const credentialsService = new UserCredentialsService();\n const hashedPassword = await credentialsService.protect(validated.password);\n\n const merged = this.repository.merge(entity, {\n reset_at: new Date().toISOString(),\n reset_hash: null,\n reset_expires: null,\n password: hashedPassword,\n });\n\n await this.repository.save(merged);\n\n return { reset_at: merged.reset_at! };\n }\n\n private async runForgotPasswordValidator(data: Record<string, any>) {\n const validator = new Container<any>({});\n\n const oneOfContainer = new Container({ oneOf: true });\n\n oneOfContainer.mount('email', createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .trim()\n .toLowerCase()\n .isEmail()\n .matches(/^[^A-Z]+$/)\n .withMessage('Email must be lowercase.');\n }));\n\n oneOfContainer.mount(\n 'name',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isString()\n .trim()\n .toLowerCase();\n }),\n );\n\n validator.mount(oneOfContainer);\n\n validator.mount(\n 'realm_id',\n { optional: true },\n createValidator(() => {\n const chain = createValidationChain();\n return chain.exists()\n .isUUID()\n .optional({ values: 'null' });\n }),\n );\n\n return validator.run(data);\n }\n\n private async runResetPasswordValidator(data: Record<string, any>) {\n const validator = new Container<any>({});\n\n const oneOfContainer = new Container({ oneOf: true });\n oneOfContainer.mount(\n 'email',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .trim()\n .toLowerCase()\n .isEmail()\n .matches(/^[^A-Z]+$/)\n .withMessage('Email must be lowercase.');\n }),\n );\n oneOfContainer.mount(\n 'name',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isString()\n .trim()\n .toLowerCase();\n }),\n );\n\n validator.mount(oneOfContainer);\n\n validator.mount(\n 'realm_id',\n { optional: true },\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .isUUID()\n .optional({ values: 'null' });\n }),\n );\n\n validator.mount(\n 'token',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isLength({\n min: 3,\n max: 256, \n });\n }),\n );\n\n validator.mount(\n 'password',\n createValidator(() => {\n const chain = createValidationChain();\n return chain\n .exists()\n .notEmpty()\n .isLength({\n min: 5,\n max: 512, \n });\n }),\n );\n\n return validator.run(data);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../src/core/identity/provider/account/module.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,uBAAuB,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACH,aAAa,EAIhB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,+BAA+B,EAAE,kCAAkC,EAAE,qCAAqC,EAAE,MAAM,YAAY,CAAC;AAE7I,qBAAa,8BAA+B,YAAW,+BAA+B;IAClF,SAAS,CAAC,gBAAgB,EAAG,uBAAuB,CAAC;IAErD,SAAS,CAAC,gBAAgB,EAAG,uBAAuB,CAAC;IAErD,SAAS,CAAC,UAAU,EAAG,uBAAuB,CAAC;IAE/C,SAAS,CAAC,UAAU,EAAG,kCAAkC,CAAC;IAE1D,SAAS,CAAC,cAAc,EAAE,uBAAuB,CAAC;IAElD,SAAS,CAAC,aAAa,EAAG,aAAa,CAAC;gBAE5B,GAAG,EAAE,qCAAqC;IAUhD,IAAI,CAAC,QAAQ,EAAE,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAmC1E,QAAQ,CACV,QAAQ,EAAE,wBAAwB,EAClC,IAAI,CAAC,EAAE,IAAI,GACZ,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../../../src/core/identity/provider/account/module.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,uBAAuB,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACH,aAAa,EAIhB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,+BAA+B,EAAE,kCAAkC,EAAE,qCAAqC,EAAE,MAAM,YAAY,CAAC;AAE7I,qBAAa,8BAA+B,YAAW,+BAA+B;IAClF,SAAS,CAAC,gBAAgB,EAAG,uBAAuB,CAAC;IAErD,SAAS,CAAC,gBAAgB,EAAG,uBAAuB,CAAC;IAErD,SAAS,CAAC,UAAU,EAAG,uBAAuB,CAAC;IAE/C,SAAS,CAAC,UAAU,EAAG,kCAAkC,CAAC;IAE1D,SAAS,CAAC,cAAc,EAAE,uBAAuB,CAAC;IAElD,SAAS,CAAC,aAAa,EAAG,aAAa,CAAC;gBAE5B,GAAG,EAAE,qCAAqC;IAUhD,IAAI,CAAC,QAAQ,EAAE,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAmC1E,QAAQ,CACV,QAAQ,EAAE,wBAAwB,EAClC,IAAI,CAAC,EAAE,IAAI,GACZ,OAAO,CAAC,IAAI,CAAC;IA0FV,kBAAkB,CACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,QAAQ,EAAE,wBAAwB,EAClC,QAAQ,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IA+ElB,eAAe,CACjB,QAAQ,EAAE,wBAAwB,EAClC,IAAI,EAAE,IAAI;IAOR,SAAS,CACX,QAAQ,EAAE,wBAAwB,EAClC,IAAI,EAAE,IAAI;CAMjB"}
|
|
@@ -67,19 +67,20 @@ var IdentityProviderAccountManager = class {
|
|
|
67
67
|
let output;
|
|
68
68
|
if (user) output = extendObject(user, attributesSelf);
|
|
69
69
|
else output = attributesSelf;
|
|
70
|
+
if (typeof output.name === "string") output.name = output.name.trim().toLowerCase();
|
|
70
71
|
let attempts = Math.max((identity.attributeCandidates?.name?.length || 0) + 1, 10);
|
|
71
72
|
while (attempts > 0) try {
|
|
72
73
|
return await this.userRepository.saveOneWithEA(output, attributesExtra);
|
|
73
74
|
} catch {
|
|
74
75
|
const names = identity.attributeCandidates?.name || [];
|
|
75
76
|
if (names.length > 0) while (names.length > 0) {
|
|
76
|
-
output.name = `${names.shift()}
|
|
77
|
+
output.name = `${names.shift()}`.trim().toLowerCase();
|
|
77
78
|
try {
|
|
78
79
|
await this.userValidator.run(output, { group: identity.operation === IdentityProviderIdentityOperation.CREATE ? ValidatorGroup.CREATE : ValidatorGroup.UPDATE });
|
|
79
80
|
break;
|
|
80
81
|
} catch {}
|
|
81
82
|
}
|
|
82
|
-
else output.name = createNanoID("
|
|
83
|
+
else output.name = createNanoID("0123456789abcdefghijklmnopqrstuvwxyz-_", 10);
|
|
83
84
|
if (isUserFakeEmail(output.email)) output.email = buildUserFakeEmail(output.name);
|
|
84
85
|
attempts -= 1;
|
|
85
86
|
}
|