Merge security fixes from 0.15 juniper releases

This commit is contained in:
tyranron 2022-02-02 19:31:30 +02:00
commit 589acb5a7b
No known key found for this signature in database
GPG key ID: 762E144FB230A4F0
30 changed files with 227 additions and 98 deletions

View file

@ -12,7 +12,7 @@ CARGO_MAKE_WORKSPACE_SKIP_MEMBERS = "integration_tests/*;examples/*;juniper_benc
[tasks.release] [tasks.release]
condition = { env_set = [ "RELEASE_LEVEL" ] } condition = { env_set = [ "RELEASE_LEVEL" ] }
command = "cargo-release" command = "cargo-release"
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--execute", "${RELEASE_LEVEL}"]
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-dry-run` to do a dry run. # Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-dry-run` to do a dry run.
@ -23,7 +23,7 @@ args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/releas
condition = { env_set = [ "RELEASE_LEVEL" ] } condition = { env_set = [ "RELEASE_LEVEL" ] }
description = "Run `cargo-release --dry-run` for every crate" description = "Run `cargo-release --dry-run` for every crate"
command = "cargo-release" command = "cargo-release"
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--dry-run", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--no-confirm", "--no-publish", "--no-push", "--no-tag", "${RELEASE_LEVEL}"]
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-local-test` to actually make changes locally but # Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-local-test` to actually make changes locally but
@ -35,4 +35,4 @@ args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/releas
condition = { env_set = [ "RELEASE_LEVEL" ] } condition = { env_set = [ "RELEASE_LEVEL" ] }
description = "Run `cargo-release` for every crate, but only make changes locally" description = "Run `cargo-release` for every crate, but only make changes locally"
command = "cargo-release" command = "cargo-release"
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--no-confirm", "${RELEASE_LEVEL}"]

View file

@ -1,6 +1,5 @@
no-dev-version = true
pre-release-commit-message = "Release {{crate_name}} {{version}}" pre-release-commit-message = "Release {{crate_name}} {{version}}"
pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}" post-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
tag-message = "Release {{crate_name}} {{version}}" tag-message = "Release {{crate_name}} {{version}}"
pre-release-replacements = [ pre-release-replacements = [
{file="CHANGELOG.md", min=0, search="# master", replace="# master\n\n- Compatibility with the latest `juniper`.\n\n# [[{{version}}] {{date}}](https://github.com/graphql-rust/juniper/releases/tag/{{crate_name}}-{{version}})"}, {file="CHANGELOG.md", min=0, search="# master", replace="# master\n\n- Compatibility with the latest `juniper`.\n\n# [[{{version}}] {{date}}](https://github.com/graphql-rust/juniper/releases/tag/{{crate_name}}-{{version}})"},

View file

@ -42,6 +42,14 @@
- Support expressions in `graphql_value!` macro. ([#996](https://github.com/graphql-rust/juniper/pull/996), [#503](https://github.com/graphql-rust/juniper/issues/503)) - Support expressions in `graphql_value!` macro. ([#996](https://github.com/graphql-rust/juniper/pull/996), [#503](https://github.com/graphql-rust/juniper/issues/503))
- List coercion rules: `null` cannot be coerced to an `[Int!]!` or `[Int]!`. ([#1004](https://github.com/graphql-rust/juniper/pull/1004)) - List coercion rules: `null` cannot be coerced to an `[Int!]!` or `[Int]!`. ([#1004](https://github.com/graphql-rust/juniper/pull/1004))
# [[0.15.9] 2022-02-02](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.9)
- Fix infinite recursion on malformed queries with nested recursive fragments. *This is a potential denial-of-service attack vector.* Thanks to [@quapka](https://github.com/quapka) for the detailed vulnerability report and reproduction steps.
# [[0.15.8] 2022-01-26](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.8)
- Fix panic on malformed queries with recursive fragments. *This is a potential denial-of-service attack vector.* Thanks to [@quapka](https://github.com/quapka) for the detailed vulnerability report and reproduction steps.
# [[0.15.7] 2021-07-08](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.7) # [[0.15.7] 2021-07-08](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.7)
- Fix panic on spreading untyped union fragments ([#945](https://github.com/graphql-rust/juniper/issues/945)) - Fix panic on spreading untyped union fragments ([#945](https://github.com/graphql-rust/juniper/issues/945))

View file

@ -1,6 +1,6 @@
[package] [package]
name = "juniper" name = "juniper"
version = "0.15.7" version = "0.15.9"
authors = [ authors = [
"Magnus Hallin <mhallin@fastmail.com>", "Magnus Hallin <mhallin@fastmail.com>",
"Christoph Herzog <chris@theduke.at>", "Christoph Herzog <chris@theduke.at>",
@ -32,7 +32,7 @@ scalar-naivetime = []
schema-language = ["graphql-parser-integration"] schema-language = ["graphql-parser-integration"]
[dependencies] [dependencies]
juniper_codegen = { version = "0.15.7", path = "../juniper_codegen" } juniper_codegen = { version = "0.15.9", path = "../juniper_codegen" }
anyhow = { version = "1.0.32", optional = true, default-features = false } anyhow = { version = "1.0.32", optional = true, default-features = false }
async-trait = "0.1.39" async-trait = "0.1.39"

View file

@ -4,13 +4,13 @@
CARGO_MAKE_CARGO_ALL_FEATURES = "" CARGO_MAKE_CARGO_ALL_FEATURES = ""
[tasks.release] [tasks.release]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--execute", "${RELEASE_LEVEL}"]
[tasks.release-dry-run] [tasks.release-dry-run]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--dry-run", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--no-publish", "--no-push", "--no-tag", "${RELEASE_LEVEL}"]
[tasks.release-local-test] [tasks.release-local-test]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "${RELEASE_LEVEL}"]
[tasks.test] [tasks.test]
args = ["test", "--all-features"] args = ["test", "--all-features"]

View file

@ -1,6 +1,5 @@
no-dev-version = true
pre-release-commit-message = "Release {{crate_name}} {{version}}" pre-release-commit-message = "Release {{crate_name}} {{version}}"
pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}" post-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
tag-message = "Release {{crate_name}} {{version}}" tag-message = "Release {{crate_name}} {{version}}"
pre-release-replacements = [ pre-release-replacements = [
# Juniper's changelog # Juniper's changelog

View file

@ -94,7 +94,7 @@ Juniper has not reached 1.0 yet, thus some API instability should be expected.
*/ */
// Due to `schema_introspection` test. // Due to `schema_introspection` test.
#![cfg_attr(test, recursion_limit = "256")] #![cfg_attr(test, recursion_limit = "256")]
#![doc(html_root_url = "https://docs.rs/juniper/0.15.7")] #![doc(html_root_url = "https://docs.rs/juniper/0.15.9")]
#![warn(missing_docs)] #![warn(missing_docs)]
// Required for using `juniper_codegen` macros inside this crate to resolve absolute `::juniper` // Required for using `juniper_codegen` macros inside this crate to resolve absolute `::juniper`

View file

@ -97,6 +97,10 @@ impl<'a, S: Debug> ValidatorContext<'a, S> {
self.errors.push(RuleError::new(message, locations)) self.errors.push(RuleError::new(message, locations))
} }
pub(crate) fn has_errors(&self) -> bool {
!self.errors.is_empty()
}
#[doc(hidden)] #[doc(hidden)]
pub fn into_errors(mut self) -> Vec<RuleError> { pub fn into_errors(mut self) -> Vec<RuleError> {
self.errors.sort(); self.errors.sort();

View file

@ -21,6 +21,7 @@ pub use self::{
#[cfg(test)] #[cfg(test)]
pub use self::test_harness::{ pub use self::test_harness::{
expect_fails_rule, expect_fails_rule_with_schema, expect_passes_rule, expect_fails_fn, expect_fails_fn_with_schema, expect_fails_rule, expect_fails_rule_with_schema,
expect_passes_fn, expect_passes_fn_with_schema, expect_passes_rule,
expect_passes_rule_with_schema, expect_passes_rule_with_schema,
}; };

View file

@ -35,7 +35,14 @@ pub fn visit_all_rules<'a, S: Debug>(ctx: &mut ValidatorContext<'a, S>, doc: &'a
where where
S: ScalarValue, S: ScalarValue,
{ {
let mut mv = MultiVisitorNil // Some validators are depending on the results of other ones.
// For example, validators checking fragments usually rely on the fact that
// they have no cycles (`no_fragment_cycles`), otherwise may stall in an
// infinite recursion. So, we should run validators in stages, moving to the
// next stage only once the previous succeeds. This is better than making
// every single validator being aware of fragments cycles and/or other
// assumptions.
let mut stage1 = MultiVisitorNil
.with(self::arguments_of_correct_type::factory()) .with(self::arguments_of_correct_type::factory())
.with(self::default_values_of_correct_type::factory()) .with(self::default_values_of_correct_type::factory())
.with(self::fields_on_correct_type::factory()) .with(self::fields_on_correct_type::factory())
@ -49,7 +56,6 @@ where
.with(self::no_undefined_variables::factory()) .with(self::no_undefined_variables::factory())
.with(self::no_unused_fragments::factory()) .with(self::no_unused_fragments::factory())
.with(self::no_unused_variables::factory()) .with(self::no_unused_variables::factory())
.with(self::overlapping_fields_can_be_merged::factory())
.with(self::possible_fragment_spreads::factory()) .with(self::possible_fragment_spreads::factory())
.with(self::provided_non_null_arguments::factory()) .with(self::provided_non_null_arguments::factory())
.with(self::scalar_leafs::factory()) .with(self::scalar_leafs::factory())
@ -60,6 +66,62 @@ where
.with(self::unique_variable_names::factory()) .with(self::unique_variable_names::factory())
.with(self::variables_are_input_types::factory()) .with(self::variables_are_input_types::factory())
.with(self::variables_in_allowed_position::factory()); .with(self::variables_in_allowed_position::factory());
visit(&mut stage1, ctx, doc);
visit(&mut mv, ctx, doc) if ctx.has_errors() {
return;
}
let mut stage2 = MultiVisitorNil.with(self::overlapping_fields_can_be_merged::factory());
visit(&mut stage2, ctx, doc);
}
#[cfg(test)]
mod tests {
use crate::{parser::SourcePosition, DefaultScalarValue};
use crate::validation::{expect_fails_fn, RuleError};
#[test]
fn handles_recursive_fragments() {
expect_fails_fn::<_, DefaultScalarValue>(
super::visit_all_rules,
"fragment f on QueryRoot { ...f }",
&[
RuleError::new(
"Fragment \"f\" is never used",
&[SourcePosition::new(0, 0, 0)],
),
RuleError::new(
"Cannot spread fragment \"f\"",
&[SourcePosition::new(26, 0, 26)],
),
],
);
}
#[test]
fn handles_nested_recursive_fragments() {
expect_fails_fn::<_, DefaultScalarValue>(
super::visit_all_rules,
"fragment f on QueryRoot { a { ...f a { ...f } } }",
&[
RuleError::new(
"Fragment \"f\" is never used",
&[SourcePosition::new(0, 0, 0)],
),
RuleError::new(
r#"Unknown field "a" on type "QueryRoot""#,
&[SourcePosition::new(26, 0, 26)],
),
RuleError::new(
"Cannot spread fragment \"f\"",
&[SourcePosition::new(30, 0, 30)],
),
RuleError::new(
"Cannot spread fragment \"f\"",
&[SourcePosition::new(39, 0, 39)],
),
],
);
}
} }

View file

@ -33,6 +33,7 @@ struct PairSet<'a> {
data: HashMap<&'a str, HashMap<&'a str, bool>>, data: HashMap<&'a str, HashMap<&'a str, bool>>,
} }
#[derive(Debug)]
struct OrderedMap<K, V> { struct OrderedMap<K, V> {
data: HashMap<K, V>, data: HashMap<K, V>,
insert_order: Vec<K>, insert_order: Vec<K>,
@ -172,13 +173,6 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
); );
for frag_name2 in &fragment_names[i + 1..] { for frag_name2 in &fragment_names[i + 1..] {
// Prevent infinite fragment recursion. This case is
// caught by fragment validators, but because the validation is
// done in parallel we can't rely on fragments being
// non-recursive here.
if frag_name1 == frag_name2 {
continue;
}
self.collect_conflicts_between_fragments( self.collect_conflicts_between_fragments(
&mut conflicts, &mut conflicts,
frag_name1, frag_name1,
@ -202,10 +196,8 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
) where ) where
S: ScalarValue, S: ScalarValue,
{ {
// Prevent infinite fragment recursion. This case is // Early return on fragment recursion, as it makes no sense.
// caught by fragment validators, but because the validation is // Fragment recursions are prevented by `no_fragment_cycles` validator.
// done in parallel we can't rely on fragments being
// non-recursive here.
if fragment_name1 == fragment_name2 { if fragment_name1 == fragment_name2 {
return; return;
} }
@ -293,10 +285,8 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
self.collect_conflicts_between(conflicts, mutually_exclusive, field_map, &field_map2, ctx); self.collect_conflicts_between(conflicts, mutually_exclusive, field_map, &field_map2, ctx);
for fragment_name2 in fragment_names2 { for fragment_name2 in fragment_names2 {
// Prevent infinite fragment recursion. This case is // Early return on fragment recursion, as it makes no sense.
// caught by fragment validators, but because the validation is // Fragment recursions are prevented by `no_fragment_cycles` validator.
// done in parallel we can't rely on fragments being
// non-recursive here.
if fragment_name == fragment_name2 { if fragment_name == fragment_name2 {
return; return;
} }
@ -2285,26 +2275,6 @@ mod tests {
); );
} }
#[test]
fn handles_recursive_fragments() {
expect_passes_rule_with_schema::<
_,
EmptyMutation<()>,
EmptySubscription<()>,
_,
_,
DefaultScalarValue,
>(
QueryRoot,
EmptyMutation::new(),
EmptySubscription::new(),
factory,
r#"
fragment f on Query { ...f }
"#,
);
}
#[test] #[test]
fn error_message_contains_hint_for_alias_conflict() { fn error_message_contains_hint_for_alias_conflict() {
assert_eq!( assert_eq!(

View file

@ -1,7 +1,7 @@
use std::mem; use std::mem;
use crate::{ use crate::{
ast::{FromInputValue, InputValue}, ast::{Document, FromInputValue, InputValue},
executor::Registry, executor::Registry,
parser::parse_document_source, parser::parse_document_source,
schema::{ schema::{
@ -834,20 +834,13 @@ where
} }
} }
pub fn validate<'a, Q, M, Sub, V, F, S>( pub fn validate<'a, Q, M, Sub, F, S>(r: Q, m: M, s: Sub, q: &'a str, visit_fn: F) -> Vec<RuleError>
r: Q,
m: M,
s: Sub,
q: &'a str,
factory: F,
) -> Vec<RuleError>
where where
S: ScalarValue + 'a, S: ScalarValue + 'a,
Q: GraphQLType<S, TypeInfo = ()>, Q: GraphQLType<S, TypeInfo = ()>,
M: GraphQLType<S, TypeInfo = ()>, M: GraphQLType<S, TypeInfo = ()>,
Sub: GraphQLType<S, TypeInfo = ()>, Sub: GraphQLType<S, TypeInfo = ()>,
V: Visitor<'a, S> + 'a, F: FnOnce(&mut ValidatorContext<'a, S>, &'a Document<S>),
F: Fn() -> V,
{ {
let mut root = RootNode::new_with_scalar_value(r, m, s); let mut root = RootNode::new_with_scalar_value(r, m, s);
@ -892,8 +885,7 @@ where
parse_document_source(q, &root.schema).expect(&format!("Parse error on input {:#?}", q)); parse_document_source(q, &root.schema).expect(&format!("Parse error on input {:#?}", q));
let mut ctx = ValidatorContext::new(unsafe { mem::transmute(&root.schema) }, &doc); let mut ctx = ValidatorContext::new(unsafe { mem::transmute(&root.schema) }, &doc);
let mut mv = MultiVisitorNil.with(factory()); visit_fn(&mut ctx, unsafe { mem::transmute(doc.as_slice()) });
visit(&mut mv, &mut ctx, unsafe { mem::transmute(doc.as_slice()) });
ctx.into_errors() ctx.into_errors()
} }
@ -907,6 +899,14 @@ where
expect_passes_rule_with_schema(QueryRoot, MutationRoot, SubscriptionRoot, factory, q); expect_passes_rule_with_schema(QueryRoot, MutationRoot, SubscriptionRoot, factory, q);
} }
pub fn expect_passes_fn<'a, F, S>(visit_fn: F, q: &'a str)
where
S: ScalarValue + 'a,
F: FnOnce(&mut ValidatorContext<'a, S>, &'a Document<S>),
{
expect_passes_fn_with_schema(QueryRoot, MutationRoot, SubscriptionRoot, visit_fn, q);
}
pub fn expect_passes_rule_with_schema<'a, Q, M, Sub, V, F, S>( pub fn expect_passes_rule_with_schema<'a, Q, M, Sub, V, F, S>(
r: Q, r: Q,
m: M, m: M,
@ -919,9 +919,12 @@ pub fn expect_passes_rule_with_schema<'a, Q, M, Sub, V, F, S>(
M: GraphQLType<S, TypeInfo = ()>, M: GraphQLType<S, TypeInfo = ()>,
Sub: GraphQLType<S, TypeInfo = ()>, Sub: GraphQLType<S, TypeInfo = ()>,
V: Visitor<'a, S> + 'a, V: Visitor<'a, S> + 'a,
F: Fn() -> V, F: FnOnce() -> V,
{ {
let errs = validate(r, m, s, q, factory); let errs = validate(r, m, s, q, move |ctx, doc| {
let mut mv = MultiVisitorNil.with(factory());
visit(&mut mv, ctx, unsafe { mem::transmute(doc) });
});
if !errs.is_empty() { if !errs.is_empty() {
print_errors(&errs); print_errors(&errs);
@ -929,6 +932,27 @@ pub fn expect_passes_rule_with_schema<'a, Q, M, Sub, V, F, S>(
} }
} }
pub fn expect_passes_fn_with_schema<'a, Q, M, Sub, F, S>(
r: Q,
m: M,
s: Sub,
visit_fn: F,
q: &'a str,
) where
S: ScalarValue + 'a,
Q: GraphQLType<S, TypeInfo = ()>,
M: GraphQLType<S, TypeInfo = ()>,
Sub: GraphQLType<S, TypeInfo = ()>,
F: FnOnce(&mut ValidatorContext<'a, S>, &'a Document<S>),
{
let errs = validate(r, m, s, q, visit_fn);
if !errs.is_empty() {
print_errors(&errs);
panic!("Expected `visit_fn` to pass, but errors found");
}
}
pub fn expect_fails_rule<'a, V, F, S>(factory: F, q: &'a str, expected_errors: &[RuleError]) pub fn expect_fails_rule<'a, V, F, S>(factory: F, q: &'a str, expected_errors: &[RuleError])
where where
S: ScalarValue + 'a, S: ScalarValue + 'a,
@ -938,6 +962,14 @@ where
expect_fails_rule_with_schema(QueryRoot, MutationRoot, factory, q, expected_errors); expect_fails_rule_with_schema(QueryRoot, MutationRoot, factory, q, expected_errors);
} }
pub fn expect_fails_fn<'a, F, S>(visit_fn: F, q: &'a str, expected_errors: &[RuleError])
where
S: ScalarValue + 'a,
F: FnOnce(&mut ValidatorContext<'a, S>, &'a Document<S>),
{
expect_fails_fn_with_schema(QueryRoot, MutationRoot, visit_fn, q, expected_errors);
}
pub fn expect_fails_rule_with_schema<'a, Q, M, V, F, S>( pub fn expect_fails_rule_with_schema<'a, Q, M, V, F, S>(
r: Q, r: Q,
m: M, m: M,
@ -949,9 +981,18 @@ pub fn expect_fails_rule_with_schema<'a, Q, M, V, F, S>(
Q: GraphQLType<S, TypeInfo = ()>, Q: GraphQLType<S, TypeInfo = ()>,
M: GraphQLType<S, TypeInfo = ()>, M: GraphQLType<S, TypeInfo = ()>,
V: Visitor<'a, S> + 'a, V: Visitor<'a, S> + 'a,
F: Fn() -> V, F: FnOnce() -> V,
{ {
let errs = validate(r, m, crate::EmptySubscription::<S>::new(), q, factory); let errs = validate(
r,
m,
crate::EmptySubscription::<S>::new(),
q,
move |ctx, doc| {
let mut mv = MultiVisitorNil.with(factory());
visit(&mut mv, ctx, unsafe { mem::transmute(doc) });
},
);
if errs.is_empty() { if errs.is_empty() {
panic!("Expected rule to fail, but no errors were found"); panic!("Expected rule to fail, but no errors were found");
@ -966,6 +1007,33 @@ pub fn expect_fails_rule_with_schema<'a, Q, M, V, F, S>(
} }
} }
pub fn expect_fails_fn_with_schema<'a, Q, M, F, S>(
r: Q,
m: M,
visit_fn: F,
q: &'a str,
expected_errors: &[RuleError],
) where
S: ScalarValue + 'a,
Q: GraphQLType<S, TypeInfo = ()>,
M: GraphQLType<S, TypeInfo = ()>,
F: FnOnce(&mut ValidatorContext<'a, S>, &'a Document<S>),
{
let errs = validate(r, m, crate::EmptySubscription::<S>::new(), q, visit_fn);
if errs.is_empty() {
panic!("Expected `visit_fn` to fail, but no errors were found");
} else if errs != expected_errors {
println!("==> Expected errors:");
print_errors(expected_errors);
println!("\n==> Actual errors:");
print_errors(&errs);
panic!("Unexpected set of errors found");
}
}
fn print_errors(errs: &[RuleError]) { fn print_errors(errs: &[RuleError]) {
for err in errs { for err in errs {
for p in err.locations() { for p in err.locations() {

View file

@ -18,7 +18,7 @@ http = "0.2.4"
actix-web = "4.0.0-beta.14" actix-web = "4.0.0-beta.14"
actix-web-actors = "4.0.0-beta.8" actix-web-actors = "4.0.0-beta.8"
juniper = { version = "0.15.7", path = "../juniper", default-features = false } juniper = { version = "0.15.9", path = "../juniper", default-features = false }
juniper_graphql_ws = { version = "0.3.0", path = "../juniper_graphql_ws", optional = true } juniper_graphql_ws = { version = "0.3.0", path = "../juniper_graphql_ws", optional = true }
anyhow = "1.0" anyhow = "1.0"
@ -36,7 +36,7 @@ tokio = "1.0"
async-stream = "0.3" async-stream = "0.3"
actix-test = "0.1.0-beta.8" actix-test = "0.1.0-beta.8"
juniper = { version = "0.15.7", path = "../juniper", features = ["expose-test-schema"] } juniper = { version = "0.15.9", path = "../juniper", features = ["expose-test-schema"] }
bytes = "1.0" bytes = "1.0"
env_logger = "0.9" env_logger = "0.9"

View file

@ -1,6 +1,6 @@
[package] [package]
name = "juniper_codegen" name = "juniper_codegen"
version = "0.15.7" version = "0.15.9"
edition = "2018" edition = "2018"
authors = [ authors = [
"Magnus Hallin <mhallin@fastmail.com>", "Magnus Hallin <mhallin@fastmail.com>",
@ -27,4 +27,4 @@ url = "2.0"
[dev-dependencies] [dev-dependencies]
derive_more = "0.99.7" derive_more = "0.99.7"
futures = "0.3" futures = "0.3"
juniper = { version = "0.15.7", path = "../juniper" } juniper = { version = "0.15.9", path = "../juniper" }

View file

@ -2,10 +2,10 @@
# release config. # release config.
[tasks.release] [tasks.release]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--execute", "${RELEASE_LEVEL}"]
[tasks.release-dry-run] [tasks.release-dry-run]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--dry-run", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--no-publish", "--no-push", "--no-tag", "${RELEASE_LEVEL}"]
[tasks.release-local-test] [tasks.release-local-test]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "${RELEASE_LEVEL}"]

View file

@ -1,6 +1,5 @@
no-dev-version = true
pre-release-commit-message = "Release {{crate_name}} {{version}}" pre-release-commit-message = "Release {{crate_name}} {{version}}"
pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}" post-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
tag-message = "Release {{crate_name}} {{version}}" tag-message = "Release {{crate_name}} {{version}}"
pre-release-replacements = [ pre-release-replacements = [
{file="../juniper/Cargo.toml", min=0, search="juniper_codegen = \\{ version = \"[^\"]+\"", replace="juniper_codegen = { version = \"{{version}}\""}, {file="../juniper/Cargo.toml", min=0, search="juniper_codegen = \\{ version = \"[^\"]+\"", replace="juniper_codegen = { version = \"{{version}}\""},

View file

@ -4,7 +4,7 @@
//! You should not depend on juniper_codegen directly. //! You should not depend on juniper_codegen directly.
//! You only need the `juniper` crate. //! You only need the `juniper` crate.
#![doc(html_root_url = "https://docs.rs/juniper_codegen/0.15.7")] #![doc(html_root_url = "https://docs.rs/juniper_codegen/0.15.9")]
#![recursion_limit = "1024"] #![recursion_limit = "1024"]
mod result; mod result;

View file

@ -10,7 +10,7 @@ repository = "https://github.com/graphql-rust/juniper"
keywords = ["apollo", "graphql", "graphql-ws", "juniper"] keywords = ["apollo", "graphql", "graphql-ws", "juniper"]
[dependencies] [dependencies]
juniper = { version = "0.15.7", path = "../juniper", default-features = false } juniper = { version = "0.15.9", path = "../juniper", default-features = false }
juniper_subscriptions = { version = "0.16.0", path = "../juniper_subscriptions" } juniper_subscriptions = { version = "0.16.0", path = "../juniper_subscriptions" }
serde = { version = "1.0.8", features = ["derive"], default-features = false } serde = { version = "1.0.8", features = ["derive"], default-features = false }
tokio = { version = "1", features = ["macros", "rt", "time"], default-features = false } tokio = { version = "1", features = ["macros", "rt", "time"], default-features = false }

View file

@ -2,13 +2,14 @@
# release config. # release config.
[tasks.release] [tasks.release]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--execute", "${RELEASE_LEVEL}"]
[tasks.release-dry-run] [tasks.release-dry-run]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--dry-run", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--no-publish", "--no-push", "--no-tag", "${RELEASE_LEVEL}"]
[tasks.release-local-test] [tasks.release-local-test]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "${RELEASE_LEVEL}"]
[env] [env]
CARGO_MAKE_CARGO_ALL_FEATURES = "" CARGO_MAKE_CARGO_ALL_FEATURES = ""

View file

@ -1,6 +1,5 @@
no-dev-version = true
pre-release-commit-message = "Release {{crate_name}} {{version}}" pre-release-commit-message = "Release {{crate_name}} {{version}}"
pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}" post-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
tag-message = "Release {{crate_name}} {{version}}" tag-message = "Release {{crate_name}} {{version}}"
pre-release-replacements = [ pre-release-replacements = [
{file="src/lib.rs", min=0, search="docs.rs/juniper_graphql_ws/[a-z0-9\\.-]+", replace="docs.rs/juniper_graphql_ws/{{version}}"}, {file="src/lib.rs", min=0, search="docs.rs/juniper_graphql_ws/[a-z0-9\\.-]+", replace="docs.rs/juniper_graphql_ws/{{version}}"},

View file

@ -6,6 +6,14 @@
- Compatibility with the latest `juniper`. - Compatibility with the latest `juniper`.
# [[0.7.3] 2022-02-02](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-v0.7.3)
- Compatibility with the latest `juniper`.
# [[0.7.2] 2022-01-26](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-v0.7.2)
- Compatibility with the latest `juniper`.
# [[0.7.1] 2021-06-07](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.7.1) # [[0.7.1] 2021-06-07](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.7.1)
- Compatibility with the latest `juniper`. - Compatibility with the latest `juniper`.

View file

@ -10,7 +10,7 @@ repository = "https://github.com/graphql-rust/juniper"
[dependencies] [dependencies]
futures = "0.3.1" futures = "0.3.1"
juniper = { version = "0.15.7", path = "../juniper", default-features = false } juniper = { version = "0.15.9", path = "../juniper", default-features = false }
hyper = { version = "0.14", features = ["server", "runtime"] } hyper = { version = "0.14", features = ["server", "runtime"] }
serde_json = "1.0" serde_json = "1.0"
tokio = "1.0" tokio = "1.0"

View file

@ -2,6 +2,14 @@
- Compatibility with the latest `juniper`. - Compatibility with the latest `juniper`.
# [[0.7.6] 2022-02-02](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-v0.7.6)
- Compatibility with the latest `juniper`.
# [[0.7.5] 2022-01-26](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-v0.7.5)
- Compatibility with the latest `juniper`.
# [[0.7.4] 2021-06-07](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.7.4) # [[0.7.4] 2021-06-07](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.7.4)
- Compatibility with the latest `juniper`. - Compatibility with the latest `juniper`.

View file

@ -1,6 +1,6 @@
[package] [package]
name = "juniper_iron" name = "juniper_iron"
version = "0.7.4" version = "0.7.6"
edition = "2018" edition = "2018"
authors = [ authors = [
"Magnus Hallin <mhallin@fastmail.com>", "Magnus Hallin <mhallin@fastmail.com>",
@ -13,13 +13,13 @@ repository = "https://github.com/graphql-rust/juniper"
[dependencies] [dependencies]
futures = "0.3.1" futures = "0.3.1"
juniper = { version = "0.15.7", path = "../juniper" } juniper = { version = "0.15.9", path = "../juniper" }
iron = ">= 0.5, < 0.7" iron = ">= 0.5, < 0.7"
serde_json = "1.0.2" serde_json = "1.0.2"
urlencoded = ">= 0.5, < 0.7" urlencoded = ">= 0.5, < 0.7"
[dev-dependencies] [dev-dependencies]
juniper = { version = "0.15.7", path = "../juniper", features = ["expose-test-schema"] } juniper = { version = "0.15.9", path = "../juniper", features = ["expose-test-schema"] }
iron-test = "0.6" iron-test = "0.6"
logger = "0.4" logger = "0.4"
mount = "0.4" mount = "0.4"

View file

@ -13,9 +13,9 @@ repository = "https://github.com/graphql-rust/juniper"
[dependencies] [dependencies]
futures = "0.3.1" futures = "0.3.1"
juniper = { version = "0.15.7", path = "../juniper", default-features = false } juniper = { version = "0.15.9", path = "../juniper", default-features = false }
rocket = { version = "0.5.0-rc.1", default-features = false } rocket = { version = "0.5.0-rc.1", default-features = false }
serde_json = "1.0.2" serde_json = "1.0.2"
[dev-dependencies] [dev-dependencies]
juniper = { version = "0.15.7", path = "../juniper", features = ["expose-test-schema"] } juniper = { version = "0.15.9", path = "../juniper", features = ["expose-test-schema"] }

View file

@ -10,7 +10,7 @@ repository = "https://github.com/graphql-rust/juniper"
[dependencies] [dependencies]
futures = "0.3.1" futures = "0.3.1"
juniper = { version = "0.15.7", path = "../juniper", default-features = false } juniper = { version = "0.15.9", path = "../juniper", default-features = false }
[dev-dependencies] [dev-dependencies]
serde_json = "1.0" serde_json = "1.0"

View file

@ -3,13 +3,13 @@
# release config. # release config.
[tasks.release] [tasks.release]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--execute", "${RELEASE_LEVEL}"]
[tasks.release-dry-run] [tasks.release-dry-run]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--dry-run", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--no-publish", "--no-push", "--no-tag", "${RELEASE_LEVEL}"]
[tasks.release-local-test] [tasks.release-local-test]
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "--skip-publish", "--skip-push", "--skip-tag", "${RELEASE_LEVEL}"] args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/release.toml", "--no-confirm", "${RELEASE_LEVEL}"]
[env] [env]
CARGO_MAKE_CARGO_ALL_FEATURES = "" CARGO_MAKE_CARGO_ALL_FEATURES = ""

View file

@ -1,6 +1,5 @@
no-dev-version = true
pre-release-commit-message = "Release {{crate_name}} {{version}}" pre-release-commit-message = "Release {{crate_name}} {{version}}"
pro-release-commit-message = "Bump {{crate_name}} version to {{next_version}}" post-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
tag-message = "Release {{crate_name}} {{version}}" tag-message = "Release {{crate_name}} {{version}}"
pre-release-replacements = [ pre-release-replacements = [
{file="../juniper_graphql_ws/Cargo.toml", min=0, search="juniper_subscriptions = \\{ version = \"[^\"]+\"", replace="juniper_subscriptions = { version = \"{{version}}\""}, {file="../juniper_graphql_ws/Cargo.toml", min=0, search="juniper_subscriptions = \\{ version = \"[^\"]+\"", replace="juniper_subscriptions = { version = \"{{version}}\""},

View file

@ -6,6 +6,10 @@
- Compatibility with the latest `juniper`. - Compatibility with the latest `juniper`.
# [[0.6.5] 2022-01-26](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-v0.6.5)
- Compatibility with the latest `juniper`.
# [[0.6.4] 2021-06-07](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.6.4) # [[0.6.4] 2021-06-07](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.6.4)
- Compatibility with the latest `juniper`. - Compatibility with the latest `juniper`.

View file

@ -14,7 +14,7 @@ subscriptions = ["juniper_graphql_ws"]
[dependencies] [dependencies]
anyhow = "1.0" anyhow = "1.0"
futures = "0.3.1" futures = "0.3.1"
juniper = { version = "0.15.7", path = "../juniper", default-features = false } juniper = { version = "0.15.9", path = "../juniper", default-features = false }
juniper_graphql_ws = { version = "0.3.0", path = "../juniper_graphql_ws", optional = true } juniper_graphql_ws = { version = "0.3.0", path = "../juniper_graphql_ws", optional = true }
serde = { version = "1.0.75", features = ["derive"] } serde = { version = "1.0.75", features = ["derive"] }
serde_json = "1.0.24" serde_json = "1.0.24"
@ -24,7 +24,7 @@ warp = "0.3"
[dev-dependencies] [dev-dependencies]
env_logger = "0.9" env_logger = "0.9"
juniper = { version = "0.15.7", path = "../juniper", features = ["expose-test-schema"] } juniper = { version = "0.15.9", path = "../juniper", features = ["expose-test-schema"] }
log = "0.4" log = "0.4"
percent-encoding = "2.1" percent-encoding = "2.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] } tokio = { version = "1", features = ["macros", "rt-multi-thread"] }