Add ability to configure rpc services. Needs further testing
This commit is contained in:
parent
fbd7a2229b
commit
67e3da3246
@ -9,5 +9,7 @@ export * from './middleware'
|
|||||||
export * from './redux'
|
export * from './redux'
|
||||||
export * from './renderer'
|
export * from './renderer'
|
||||||
export * from './store'
|
export * from './store'
|
||||||
export * from './team'
|
|
||||||
export * from './test-utils'
|
export * from './test-utils'
|
||||||
|
|
||||||
|
import * as team from './team'
|
||||||
|
export {team}
|
||||||
|
|||||||
@ -10,33 +10,27 @@ import {Router} from 'react-router-dom'
|
|||||||
import {Store} from 'redux'
|
import {Store} from 'redux'
|
||||||
import {createBrowserHistory} from 'history'
|
import {createBrowserHistory} from 'history'
|
||||||
|
|
||||||
export interface IClientRendererParams<A extends Action, D extends IAPIDef> {
|
export interface IClientRendererParams<Props> {
|
||||||
readonly RootComponent: React.ComponentType<{
|
readonly RootComponent: React.ComponentType<Props>
|
||||||
config: IClientConfig,
|
|
||||||
http: IHTTPClient<D>
|
|
||||||
}>,
|
|
||||||
readonly target?: HTMLElement
|
readonly target?: HTMLElement
|
||||||
readonly hydrate: boolean // TODO make this better
|
readonly hydrate: boolean // TODO make this better
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ClientRenderer<A extends Action, D extends IAPIDef>
|
export class ClientRenderer<Props>
|
||||||
implements IRenderer {
|
implements IRenderer<Props> {
|
||||||
constructor(readonly params: IClientRendererParams<A, D>) {}
|
constructor(readonly params: IClientRendererParams<Props>) {}
|
||||||
|
|
||||||
render<State>(
|
render<State>(
|
||||||
url: string,
|
url: string,
|
||||||
store: Store<State>,
|
store: Store<State>,
|
||||||
config = (window as any).__APP_CONFIG__ as IClientConfig,
|
props: Props,
|
||||||
|
config: IClientConfig,
|
||||||
) {
|
) {
|
||||||
const {
|
const {
|
||||||
RootComponent,
|
RootComponent,
|
||||||
target = document.getElementById('container'),
|
target = document.getElementById('container'),
|
||||||
} = this.params
|
} = this.params
|
||||||
|
|
||||||
const http = new HTTPClient<D>(config.baseUrl + '/api', {
|
|
||||||
'x-csrf-token': config.csrfToken,
|
|
||||||
})
|
|
||||||
|
|
||||||
const history = createBrowserHistory({
|
const history = createBrowserHistory({
|
||||||
basename: config.baseUrl,
|
basename: config.baseUrl,
|
||||||
})
|
})
|
||||||
@ -45,7 +39,7 @@ export class ClientRenderer<A extends Action, D extends IAPIDef>
|
|||||||
ReactDOM.hydrate(
|
ReactDOM.hydrate(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<Router history={history}>
|
<Router history={history}>
|
||||||
<RootComponent config={config} http={http} />
|
<RootComponent {...props} />
|
||||||
</Router>
|
</Router>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
target,
|
target,
|
||||||
@ -54,7 +48,7 @@ export class ClientRenderer<A extends Action, D extends IAPIDef>
|
|||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<Router history={history}>
|
<Router history={history}>
|
||||||
<RootComponent config={config} http={http} />
|
<RootComponent {...props} />
|
||||||
</Router>
|
</Router>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
target,
|
target,
|
||||||
|
|||||||
@ -2,10 +2,11 @@ import {IAPIDef} from '@rondo.dev/common'
|
|||||||
import {IClientConfig} from './IClientConfig'
|
import {IClientConfig} from './IClientConfig'
|
||||||
import {Store} from 'redux'
|
import {Store} from 'redux'
|
||||||
|
|
||||||
export interface IRenderer {
|
export interface IRenderer<Props> {
|
||||||
render<State>(
|
render<State>(
|
||||||
url: string,
|
url: string,
|
||||||
store: Store<State>,
|
store: Store<State>,
|
||||||
|
props: Props,
|
||||||
config: IClientConfig,
|
config: IClientConfig,
|
||||||
): any
|
): any
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,27 +11,20 @@ import {StaticRouter} from 'react-router-dom'
|
|||||||
import {Store} from 'redux'
|
import {Store} from 'redux'
|
||||||
import {renderToNodeStream} from 'react-dom/server'
|
import {renderToNodeStream} from 'react-dom/server'
|
||||||
|
|
||||||
export class ServerRenderer<A extends Action, D extends IAPIDef>
|
export class ServerRenderer<Props> implements IRenderer<Props> {
|
||||||
implements IRenderer {
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly RootComponent: React.ComponentType<{
|
readonly RootComponent: React.ComponentType<Props>,
|
||||||
config: IClientConfig,
|
|
||||||
http: IHTTPClient<D>
|
|
||||||
}>,
|
|
||||||
) {}
|
) {}
|
||||||
async render<State>(
|
async render<State>(
|
||||||
url: string,
|
url: string,
|
||||||
store: Store<State>,
|
store: Store<State>,
|
||||||
|
props: Props,
|
||||||
config: IClientConfig,
|
config: IClientConfig,
|
||||||
host: string = '',
|
host: string = '',
|
||||||
headers: Record<string, string> = {},
|
headers: Record<string, string> = {},
|
||||||
) {
|
) {
|
||||||
const {RootComponent} = this
|
const {RootComponent} = this
|
||||||
// TODO set cookie in headers here...
|
// TODO set cookie in headers here...
|
||||||
const http = new HTTPClient<D>(
|
|
||||||
'http://' + host + config.baseUrl + '/api',
|
|
||||||
headers,
|
|
||||||
)
|
|
||||||
|
|
||||||
const context: StaticRouterContext = {}
|
const context: StaticRouterContext = {}
|
||||||
|
|
||||||
@ -42,7 +35,7 @@ export class ServerRenderer<A extends Action, D extends IAPIDef>
|
|||||||
location={url}
|
location={url}
|
||||||
context={context}
|
context={context}
|
||||||
>
|
>
|
||||||
<RootComponent config={config} http={http} />
|
<RootComponent {...props} />
|
||||||
</StaticRouter>
|
</StaticRouter>
|
||||||
</Provider>
|
</Provider>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -40,10 +40,7 @@ describe('TeamConnector', () => {
|
|||||||
reducers: {Team: Feature.Team},
|
reducers: {Team: Feature.Team},
|
||||||
select: state => state.Team,
|
select: state => state.Team,
|
||||||
})
|
})
|
||||||
.withComponent(select =>
|
.withComponent(select => Feature.configure(teamActions, select))
|
||||||
new Feature
|
|
||||||
.TeamConnector(teamActions)
|
|
||||||
.connect(select))
|
|
||||||
.withJSX((Component, props) =>
|
.withJSX((Component, props) =>
|
||||||
<MemoryRouter initialEntries={historyEntries}>
|
<MemoryRouter initialEntries={historyEntries}>
|
||||||
<Component {...props} />
|
<Component {...props} />
|
||||||
|
|||||||
@ -1,37 +1,32 @@
|
|||||||
import {Connector} from '../redux/Connector'
|
import {Connector} from '../redux/Connector'
|
||||||
import {TStateSelector} from '../redux'
|
import {pack, TStateSelector} from '../redux'
|
||||||
import {ITeamState} from './TeamReducer'
|
import {ITeamState} from './TeamReducer'
|
||||||
import {TeamActions} from './TeamActions'
|
import {TeamActions} from './TeamActions'
|
||||||
import {TeamManager} from './TeamManager'
|
import {TeamManager} from './TeamManager'
|
||||||
import {bindActionCreators} from 'redux'
|
import {bindActionCreators} from 'redux'
|
||||||
import {withRouter} from 'react-router-dom'
|
import {withRouter} from 'react-router-dom'
|
||||||
|
|
||||||
export class TeamConnector extends Connector<ITeamState> {
|
export function configure<State>(
|
||||||
constructor(protected readonly teamActions: TeamActions) {
|
teamActions: TeamActions,
|
||||||
super()
|
getLocalState: TStateSelector<State, ITeamState>,
|
||||||
}
|
) {
|
||||||
|
const Component = pack(
|
||||||
|
getLocalState,
|
||||||
|
state => ({...state}),
|
||||||
|
d => ({
|
||||||
|
addUser: bindActionCreators(teamActions.addUser, d),
|
||||||
|
removeUser: bindActionCreators(teamActions.removeUser, d),
|
||||||
|
createTeam: bindActionCreators(teamActions.createTeam, d),
|
||||||
|
updateTeam: bindActionCreators(teamActions.updateTeam, d),
|
||||||
|
removeTeam: bindActionCreators(teamActions.removeTeam, d),
|
||||||
|
fetchMyTeams: bindActionCreators(teamActions.fetchMyTeams, d),
|
||||||
|
fetchUsersInTeam:
|
||||||
|
bindActionCreators(teamActions.fetchUsersInTeam, d),
|
||||||
|
findUserByEmail:
|
||||||
|
bindActionCreators(teamActions.findUserByEmail, d),
|
||||||
|
}),
|
||||||
|
TeamManager,
|
||||||
|
)
|
||||||
|
|
||||||
connect<State>(getLocalState: TStateSelector<State, ITeamState>) {
|
return Component
|
||||||
const Component = this.wrap(
|
|
||||||
getLocalState,
|
|
||||||
state => ({
|
|
||||||
...state,
|
|
||||||
}),
|
|
||||||
d => ({
|
|
||||||
addUser: bindActionCreators(this.teamActions.addUser, d),
|
|
||||||
removeUser: bindActionCreators(this.teamActions.removeUser, d),
|
|
||||||
createTeam: bindActionCreators(this.teamActions.createTeam, d),
|
|
||||||
updateTeam: bindActionCreators(this.teamActions.updateTeam, d),
|
|
||||||
removeTeam: bindActionCreators(this.teamActions.removeTeam, d),
|
|
||||||
fetchMyTeams: bindActionCreators(this.teamActions.fetchMyTeams, d),
|
|
||||||
fetchUsersInTeam:
|
|
||||||
bindActionCreators(this.teamActions.fetchUsersInTeam, d),
|
|
||||||
findUserByEmail:
|
|
||||||
bindActionCreators(this.teamActions.findUserByEmail, d),
|
|
||||||
}),
|
|
||||||
TeamManager,
|
|
||||||
)
|
|
||||||
|
|
||||||
return Component
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
8
packages/common/src/rpc.ts
Normal file
8
packages/common/src/rpc.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import {IContext} from './IContext'
|
||||||
|
import {ITeamService} from './team'
|
||||||
|
import {IUserService} from './user'
|
||||||
|
|
||||||
|
export interface IRPCServices {
|
||||||
|
userService: IUserService
|
||||||
|
teamService: ITeamService
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import * as util from './util'
|
import * as util from './bulk'
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import {Contextual} from './types'
|
import {Contextual} from './types'
|
||||||
import {jsonrpc} from './express'
|
import {jsonrpc} from './express'
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import {IJSONRPCReturnType} from './express'
|
import {IJSONRPCReturnType} from './express'
|
||||||
import {TAsyncified, TReduxed} from './types'
|
import {Contextual, TAsyncified, TReduxed} from './types'
|
||||||
import {createActions} from './redux'
|
import {createActions} from './redux'
|
||||||
import {createLocalClient, LocalClient} from './local'
|
import {createLocalClient, LocalClient} from './local'
|
||||||
|
|
||||||
@ -7,9 +7,12 @@ function keys<T>(obj: T): Array<keyof T & string> {
|
|||||||
return Object.keys(obj) as Array<keyof T & string>
|
return Object.keys(obj) as Array<keyof T & string>
|
||||||
}
|
}
|
||||||
|
|
||||||
type BulkLocalClient<T> = {[K in keyof T & string]: LocalClient<T[K]>}
|
export type BulkServices<T, Cx> = {
|
||||||
type BulkActions<T> = {[K in keyof T & string]: TReduxed<T[K], K>}
|
[K in keyof T & string]: Contextual<T[K], Cx>
|
||||||
type BulkRemoteClient<T> = {[K in keyof T & string]: TAsyncified<T[K]>}
|
}
|
||||||
|
export type BulkLocalClient<T> = {[K in keyof T & string]: LocalClient<T[K]>}
|
||||||
|
export type BulkActions<T> = {[K in keyof T & string]: TReduxed<T[K], K>}
|
||||||
|
export type BulkClient<T> = {[K in keyof T & string]: TAsyncified<T[K]>}
|
||||||
|
|
||||||
function bulkCreate<T, R>(
|
function bulkCreate<T, R>(
|
||||||
src: T,
|
src: T,
|
||||||
@ -22,7 +25,7 @@ function bulkCreate<T, R>(
|
|||||||
}, {} as any)
|
}, {} as any)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bulkCreateLocalClient<T, Cx>(
|
export function bulkCreateLocalClient<Cx, T extends Contextual<{}, Cx>>(
|
||||||
src: T,
|
src: T,
|
||||||
context: Cx,
|
context: Cx,
|
||||||
): BulkLocalClient<T> {
|
): BulkLocalClient<T> {
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
export * from './bulk'
|
||||||
export * from './ensure'
|
export * from './ensure'
|
||||||
export * from './error'
|
export * from './error'
|
||||||
export * from './express'
|
export * from './express'
|
||||||
@ -6,4 +7,3 @@ export * from './local'
|
|||||||
export * from './redux'
|
export * from './redux'
|
||||||
export * from './remote'
|
export * from './remote'
|
||||||
export * from './types'
|
export * from './types'
|
||||||
export * from './util'
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import {IApplication} from './IApplication'
|
|||||||
import {IConfig} from './IConfig'
|
import {IConfig} from './IConfig'
|
||||||
import {IDatabase} from '../database/IDatabase'
|
import {IDatabase} from '../database/IDatabase'
|
||||||
import {ILogger} from '../logger/ILogger'
|
import {ILogger} from '../logger/ILogger'
|
||||||
import {IRoutes} from '@rondo.dev/common'
|
import {IRoutes, IContext} from '@rondo.dev/common'
|
||||||
import {IServices} from './IServices'
|
import {IServices} from './IServices'
|
||||||
import {ITransactionManager} from '../database/ITransactionManager'
|
import {ITransactionManager} from '../database/ITransactionManager'
|
||||||
import {loggerFactory} from '../logger'
|
import {loggerFactory} from '../logger'
|
||||||
@ -112,9 +112,13 @@ export class Application implements IApplication {
|
|||||||
).handle)
|
).handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getContext(req: express.Request): IContext {
|
||||||
|
return {user: req.user}
|
||||||
|
}
|
||||||
|
|
||||||
protected jsonrpc() {
|
protected jsonrpc() {
|
||||||
return jsonrpc(
|
return jsonrpc(
|
||||||
req => ({user: req.user}),
|
req => this.getContext(req),
|
||||||
this.getApiLogger(),
|
this.getApiLogger(),
|
||||||
(path, service, callback) => this
|
(path, service, callback) => this
|
||||||
.database
|
.database
|
||||||
@ -124,17 +128,7 @@ export class Application implements IApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected configureRPC(router: express.Router) {
|
protected configureRPC(router: express.Router) {
|
||||||
router.use(
|
// Override this method
|
||||||
'/rpc',
|
|
||||||
this.jsonrpc()
|
|
||||||
.addService('/team',
|
|
||||||
new rpc.TeamService(this.database, this.services.userPermissions),
|
|
||||||
keys<rpc.TeamService>())
|
|
||||||
.addService('/user',
|
|
||||||
new rpc.UserService(this.database),
|
|
||||||
keys<rpc.UserService>())
|
|
||||||
.router(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected configureApiErrorHandling(router: express.Router) {
|
protected configureApiErrorHandling(router: express.Router) {
|
||||||
|
|||||||
@ -18,7 +18,7 @@ export class TeamService implements RPC<t.ITeamService> {
|
|||||||
protected readonly permissions: IUserPermissions,
|
protected readonly permissions: IUserPermissions,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async create(params: t.ITeamCreateParams, context: IContext) {
|
async create(context: IContext, params: t.ITeamCreateParams) {
|
||||||
const userId = context.user!.id
|
const userId = context.user!.id
|
||||||
const name = trim(params.name)
|
const name = trim(params.name)
|
||||||
|
|
||||||
@ -32,17 +32,17 @@ export class TeamService implements RPC<t.ITeamService> {
|
|||||||
userId,
|
userId,
|
||||||
})
|
})
|
||||||
|
|
||||||
await this.addUser({
|
await this.addUser(context, {
|
||||||
teamId: team.id,
|
teamId: team.id,
|
||||||
userId,
|
userId,
|
||||||
// ADMIN role
|
// ADMIN role
|
||||||
roleId: 1,
|
roleId: 1,
|
||||||
}, context)
|
})
|
||||||
|
|
||||||
return team
|
return team
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove({id}: t.ITeamRemoveParams, context: IContext) {
|
async remove(context: IContext, {id}: t.ITeamRemoveParams) {
|
||||||
const userId = context.user!.id
|
const userId = context.user!.id
|
||||||
|
|
||||||
await this.permissions.belongsToTeam({
|
await this.permissions.belongsToTeam({
|
||||||
@ -59,7 +59,7 @@ export class TeamService implements RPC<t.ITeamService> {
|
|||||||
return {id}
|
return {id}
|
||||||
}
|
}
|
||||||
|
|
||||||
async update({id, name}: t.ITeamUpdateParams, context: IContext) {
|
async update(context: IContext, {id, name}: t.ITeamUpdateParams) {
|
||||||
const userId = context.user!.id
|
const userId = context.user!.id
|
||||||
|
|
||||||
await this.permissions.belongsToTeam({
|
await this.permissions.belongsToTeam({
|
||||||
@ -74,15 +74,15 @@ export class TeamService implements RPC<t.ITeamService> {
|
|||||||
name,
|
name,
|
||||||
})
|
})
|
||||||
|
|
||||||
return (await this.findOne(id))!
|
return (await this.findOne(context, id))!
|
||||||
}
|
}
|
||||||
|
|
||||||
async addUser(params: t.ITeamAddUserParams, context: IContext) {
|
async addUser(context: IContext, params: t.ITeamAddUserParams) {
|
||||||
const {userId, teamId, roleId} = params
|
const {userId, teamId, roleId} = params
|
||||||
await this.db.getRepository(UserTeam)
|
await this.db.getRepository(UserTeam)
|
||||||
.save({userId, teamId, roleId})
|
.save({userId, teamId, roleId})
|
||||||
|
|
||||||
const userTeam = await this.createFindUserInTeamQuery()
|
const userTeam = await this._createFindUserInTeamQuery()
|
||||||
.where({
|
.where({
|
||||||
userId,
|
userId,
|
||||||
teamId,
|
teamId,
|
||||||
@ -90,10 +90,10 @@ export class TeamService implements RPC<t.ITeamService> {
|
|||||||
})
|
})
|
||||||
.getOne()
|
.getOne()
|
||||||
|
|
||||||
return this.mapUserInTeam(userTeam!)
|
return this._mapUserInTeam(userTeam!)
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeUser(params: t.ITeamAddUserParams, context: IContext) {
|
async removeUser(context: IContext, params: t.ITeamAddUserParams) {
|
||||||
const {teamId, userId, roleId} = params
|
const {teamId, userId, roleId} = params
|
||||||
|
|
||||||
await this.permissions.belongsToTeam({
|
await this.permissions.belongsToTeam({
|
||||||
@ -108,7 +108,7 @@ export class TeamService implements RPC<t.ITeamService> {
|
|||||||
return {teamId, userId, roleId}
|
return {teamId, userId, roleId}
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(id: number) {
|
async findOne(context: IContext, id: number) {
|
||||||
return this.db.getRepository(Team).findOne(id)
|
return this.db.getRepository(Team).findOne(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ export class TeamService implements RPC<t.ITeamService> {
|
|||||||
.getMany()
|
.getMany()
|
||||||
}
|
}
|
||||||
|
|
||||||
async findUsers(teamId: number, context: IContext) {
|
async findUsers(context: IContext, teamId: number) {
|
||||||
const userId = context.user!.id
|
const userId = context.user!.id
|
||||||
|
|
||||||
await this.permissions.belongsToTeam({
|
await this.permissions.belongsToTeam({
|
||||||
@ -131,16 +131,16 @@ export class TeamService implements RPC<t.ITeamService> {
|
|||||||
userId,
|
userId,
|
||||||
})
|
})
|
||||||
|
|
||||||
const userTeams = await this.createFindUserInTeamQuery()
|
const userTeams = await this._createFindUserInTeamQuery()
|
||||||
.where('ut.teamId = :teamId', {
|
.where('ut.teamId = :teamId', {
|
||||||
teamId,
|
teamId,
|
||||||
})
|
})
|
||||||
.getMany()
|
.getMany()
|
||||||
|
|
||||||
return userTeams.map(this.mapUserInTeam)
|
return userTeams.map(this._mapUserInTeam)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected mapUserInTeam(ut: UserTeam): IUserInTeam {
|
protected _mapUserInTeam(ut: UserTeam): IUserInTeam {
|
||||||
return {
|
return {
|
||||||
teamId: ut.teamId,
|
teamId: ut.teamId,
|
||||||
userId: ut.userId,
|
userId: ut.userId,
|
||||||
@ -150,7 +150,7 @@ export class TeamService implements RPC<t.ITeamService> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected createFindUserInTeamQuery() {
|
protected _createFindUserInTeamQuery() {
|
||||||
return this.db.getRepository(UserTeam)
|
return this.db.getRepository(UserTeam)
|
||||||
.createQueryBuilder('ut')
|
.createQueryBuilder('ut')
|
||||||
.select('ut')
|
.select('ut')
|
||||||
|
|||||||
@ -13,7 +13,7 @@ const MIN_PASSWORD_LENGTH = 10
|
|||||||
export class UserService implements RPC<u.IUserService> {
|
export class UserService implements RPC<u.IUserService> {
|
||||||
constructor(protected readonly db: IDatabase) {}
|
constructor(protected readonly db: IDatabase) {}
|
||||||
|
|
||||||
async changePassword(params: u.IChangePasswordParams, context: IContext) {
|
async changePassword(context: IContext, params: u.IChangePasswordParams) {
|
||||||
const userId = context.user!.id
|
const userId = context.user!.id
|
||||||
const {oldPassword, newPassword} = params
|
const {oldPassword, newPassword} = params
|
||||||
const userRepository = this.db.getRepository(User)
|
const userRepository = this.db.getRepository(User)
|
||||||
@ -27,12 +27,12 @@ export class UserService implements RPC<u.IUserService> {
|
|||||||
if (!(user && isValid)) {
|
if (!(user && isValid)) {
|
||||||
throw createError(400, 'Passwords do not match')
|
throw createError(400, 'Passwords do not match')
|
||||||
}
|
}
|
||||||
const password = await this.hash(newPassword)
|
const password = await this._hash(newPassword)
|
||||||
await userRepository
|
await userRepository
|
||||||
.update(userId, { password })
|
.update(userId, { password })
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(id: number) {
|
async findOne(context: IContext, id: number) {
|
||||||
const user = await this.db.getRepository(User).findOne(id, {
|
const user = await this.db.getRepository(User).findOne(id, {
|
||||||
relations: ['emails'],
|
relations: ['emails'],
|
||||||
})
|
})
|
||||||
@ -49,7 +49,7 @@ export class UserService implements RPC<u.IUserService> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async findUserByEmail(email: string) {
|
async findUserByEmail(context: IContext, email: string) {
|
||||||
const userEmail = await this.db.getRepository(UserEmail)
|
const userEmail = await this.db.getRepository(UserEmail)
|
||||||
.findOne({ email }, {
|
.findOne({ email }, {
|
||||||
relations: ['user'],
|
relations: ['user'],
|
||||||
@ -69,7 +69,7 @@ export class UserService implements RPC<u.IUserService> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async hash(password: string): Promise<string> {
|
protected async _hash(password: string): Promise<string> {
|
||||||
return hash(password, SALT_ROUNDS)
|
return hash(password, SALT_ROUNDS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user