export async function createUser(server: Server, request: Request, reply: IReply) { const payload = request.payload as {name: string, username: string, password: string, accountId: string}; const account = await Accounts.Database.get<Account>(payload.accountId.toLowerCase()); if (!account) { return reply(notAcceptable(`No account with id of ${payload.accountId} exists.`)); } // Ensure adding another user won't go over the account's plan limit. const userCount = await Users.countByAccountId(payload.accountId.toLowerCase()); const plan = findPlan(account.planId); if (userCount >= plan.totalUsers) { return reply(notAcceptable("Account's plan has reached its maximum number of users.")); } let user: User = { _id: payload.username, _rev: undefined, accountId: payload.accountId.toLowerCase(), hashedPassword: hashSync(payload.password, 10), name: payload.name, } try { const update = await Users.Database.put(user); if (!update.ok) { return reply(expectationFailed("Failed to create user.", update)); } user._rev = update.rev; } catch (e) { console.error("Error thrown when creating user", e); throw e; } // Do not reflect the user's hashedPassword. user.hashedPassword = undefined; return reply(user).code(201); }
export function getSearchDsl( mappings: IndexMapping, schema: SavedObjectsSchema, options: GetSearchDslOptions ) { const { type, search, defaultSearchOperator, searchFields, sortField, sortOrder, namespace, hasReference, } = options; if (!type) { throw Boom.notAcceptable('type must be specified'); } if (sortOrder && !sortField) { throw Boom.notAcceptable('sortOrder requires a sortField'); } return { ...getQueryParams( mappings, schema, namespace, type, search, searchFields, defaultSearchOperator, hasReference ), ...getSortingParams(mappings, type, sortField, sortOrder), }; }
handler: async function (req, res, next) { const query: Requests.GetOauthUrl = req.validatedQuery; const isValidUrl = await Auth.isValidShopifyDomain(req.validatedQuery.shop_domain); if (!isValidUrl) { return next(boom.notAcceptable(`${query.shop_domain} is not a valid Shopify shop domain.`)); } const authUrl = await Auth.buildAuthorizationUrl(Constants.DEFAULT_SCOPES, req.validatedQuery.shop_domain, Constants.SHOPIFY_API_KEY, query.redirect_url); res.json({ url: authUrl }); return next(); }
return async function errorHandlerMiddleware(ctx, next) { try { await next(); if (ctx.status === 404) throw Boom.notFound(); } catch (applicationError) { const err: ApplicationError = applicationError; let error: Boom<any>; // Normalize error object try { if (!(applicationError instanceof Error)) throw new Error('Cannot handle non-errors as errors'); error = Boom.isBoom(err) ? err : Boom.boomify(err, { statusCode: err.status || err.statusCode || undefined, decorate: err.data, }); } catch (subError) { error = Boom.boomify(subError); } // Set defaults let status = Boom.notAcceptable().output.statusCode; let headers = {}; let body: string | object = Boom.notAcceptable().output.payload.message; // Check for dev and include dev stuff if (ctx.app.env !== 'production') { error.output.payload.additionalDevelopmentData = { data: error.data || undefined, stack: error.isServer && error.stack ? error.stack : undefined, }; } // Convert boom response to proper format const payload = { error: { code: error.output.payload.code || '', status: error.output.payload.statusCode, error: error.output.payload.error, message: error.output.payload.message, errors: error.output.payload.errors, additionalDevelopmentData: error.output.payload.additionalDevelopmentData, }, }; // Respond with the proper format const format = ctx.accepts(['json', 'text']); if (format === 'json') { status = error.output.statusCode; headers = error.output.headers; body = payload; } else if (format === 'text') { status = error.output.statusCode; headers = error.output.headers; body = payload.error.message; } // Respond with the error ctx.set(headers); ctx.status = status; ctx.body = body; } };