Как связать логин в Hapi.js?

Я пытаюсь проверить JSON, отправленный через запрос POST. Я использую валидатор JOI для hapijs. JSON не может одновременно иметь и пароль, и токен доступа, но если пользователь является гостем, эта проверка игнорируется.

validate: {
      payload: Joi.object({
        isGuest: Joi.boolean().required(),
        username: Joi.string().when('isGuest', { is: false, then: Joi.required() }),
        password: Joi.string().alphanum(),
        accessToken: Joi.string().alphanum(),
      }).options({ allowUnknown: true }).xor('password', 'accessToken'),
    },

Логика, которую я пытаюсь реализовать, будет выглядеть примерно так.

OR('isGuest', XOR(AND('username','password'), 'accessToken'))

Я не могу понять, как реализовать это, используя доступные инструменты.

1 ответ

Решение

Ты можешь использовать without

const schema = Joi.object().keys({
  isGuest: Joi.boolean(),
  password: Joi.string().alphanum(),
  accessToken: Joi.string().alphanum(),
}).without('isGuest', ['password', 'accessToken'])
  .without('password', 'accessToken');

Вот тестовые случаи

const object1 = { isGuest: true }
console.log(Joi.validate(object1, schema)); // pass

const object2 = { password: 'asdfads' }
console.log(Joi.validate(object2, schema)); // pass

const object3 = { accessToken: 'asdfads' }
console.log(Joi.validate(object3, schema)); // pass

const object4 = { isGuest: true, password: "asdf" }
console.log(Joi.validate(object4, schema)); // fail

const object5 = { isGuest: true, accessToken: "asdf" }
console.log(Joi.validate(object5, schema)); // fail

const object6 = { password: "asdf", accessToken: "asdf" }
console.log(Joi.validate(object6, schema)); // fail

Если вы также заинтересованы в значении, вы можете использовать эту схему

const schema = Joi.object().keys({
  isGuest: Joi.boolean(),
  password: Joi.string().alphanum(),
  accessToken: Joi.string().alphanum(),
}).when(Joi.object({
  isGuest: Joi.boolean().required().valid(true),
  password: Joi.string().alphanum().optional(),
  accessToken: Joi.string().alphanum().optional(),
}), {
    then: Joi.object({
      password: Joi.string().alphanum().optional(),
      accessToken: Joi.string().alphanum().optional(),
    }),
    otherwise: Joi.object({
      password: Joi.string().alphanum(),
      accessToken: Joi.string().alphanum(),
    }).xor('password', 'accessToken'),
  });

const object1 = { isGuest: true }
console.log(Joi.validate(object1, schema)); // pass

const object4 = { isGuest: true, password: "asdf" }
console.log(Joi.validate(object4, schema)); // pass

const object5 = { isGuest: true, accessToken: "asdf" }
console.log(Joi.validate(object5, schema)); // pass

const object7 = { isGuest: true, password: "abc", accessToken: "1234" }
console.log(Joi.validate(object7, schema)); // pass

const object2 = { isGuest: false, password: 'asdfads' }
console.log(Joi.validate(object2, schema)); // pass

const object31 = { isGuest: false, accessToken: 'asdfads' }
console.log(Joi.validate(object31, schema)); // pass

const object21 = { password: 'asdfads' }
console.log(Joi.validate(object21, schema)); // pass

const object3 = { accessToken: 'asdfads' }
console.log(Joi.validate(object3, schema)); // pass

console.log('Failure cases');

const object11 = { isGuest: false }
console.log(Joi.validate(object11, schema)); // fail

const object6 = { isGuest: false, password: "asdf", accessToken: "asdf" }
console.log(Joi.validate(object6, schema)); // fail
Другие вопросы по тегам