diff --git a/Cargo.lock b/Cargo.lock index 73d8149f6..29623ffdb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3104,7 +3104,7 @@ dependencies = [ [[package]] name = "mas-axum-utils" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "axum", @@ -3138,7 +3138,7 @@ dependencies = [ [[package]] name = "mas-cli" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "axum", @@ -3211,7 +3211,7 @@ dependencies = [ [[package]] name = "mas-config" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "camino", @@ -3243,7 +3243,7 @@ dependencies = [ [[package]] name = "mas-context" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "console", "opentelemetry", @@ -3259,7 +3259,7 @@ dependencies = [ [[package]] name = "mas-data-model" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "base64ct", "chrono", @@ -3282,7 +3282,7 @@ dependencies = [ [[package]] name = "mas-email" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "async-trait", "lettre", @@ -3293,7 +3293,7 @@ dependencies = [ [[package]] name = "mas-handlers" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "aide", "anyhow", @@ -3373,7 +3373,7 @@ dependencies = [ [[package]] name = "mas-http" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "futures-util", "headers", @@ -3394,7 +3394,7 @@ dependencies = [ [[package]] name = "mas-i18n" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "camino", "icu_calendar", @@ -3416,7 +3416,7 @@ dependencies = [ [[package]] name = "mas-i18n-scan" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "camino", "clap", @@ -3430,7 +3430,7 @@ dependencies = [ [[package]] name = "mas-iana" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "schemars 0.8.22", "serde", @@ -3438,7 +3438,7 @@ dependencies = [ [[package]] name = "mas-iana-codegen" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3454,7 +3454,7 @@ dependencies = [ [[package]] name = "mas-jose" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "base64ct", "chrono", @@ -3484,7 +3484,7 @@ dependencies = [ [[package]] name = "mas-keystore" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "aead", "base64ct", @@ -3512,7 +3512,7 @@ dependencies = [ [[package]] name = "mas-listener" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "bytes", @@ -3537,7 +3537,7 @@ dependencies = [ [[package]] name = "mas-matrix" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3547,7 +3547,7 @@ dependencies = [ [[package]] name = "mas-matrix-synapse" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3564,7 +3564,7 @@ dependencies = [ [[package]] name = "mas-oidc-client" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "assert_matches", "async-trait", @@ -3600,7 +3600,7 @@ dependencies = [ [[package]] name = "mas-policy" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "arc-swap", @@ -3617,7 +3617,7 @@ dependencies = [ [[package]] name = "mas-router" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "axum", "serde", @@ -3628,7 +3628,7 @@ dependencies = [ [[package]] name = "mas-spa" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "camino", "serde", @@ -3637,7 +3637,7 @@ dependencies = [ [[package]] name = "mas-storage" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "async-trait", "chrono", @@ -3659,7 +3659,7 @@ dependencies = [ [[package]] name = "mas-storage-pg" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "async-trait", "chrono", @@ -3686,7 +3686,7 @@ dependencies = [ [[package]] name = "mas-tasks" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3718,7 +3718,7 @@ dependencies = [ [[package]] name = "mas-templates" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "arc-swap", @@ -3748,7 +3748,7 @@ dependencies = [ [[package]] name = "mas-tower" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "http", "opentelemetry", @@ -4018,7 +4018,7 @@ dependencies = [ [[package]] name = "oauth2-types" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "assert_matches", "base64ct", @@ -6100,7 +6100,7 @@ dependencies = [ [[package]] name = "syn2mas" -version = "1.4.0-rc.0" +version = "1.4.0-rc.1" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index 7c5d3a902..92b80de2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = ["crates/*"] resolver = "2" # Updated in the CI with a `sed` command -package.version = "1.4.0-rc.0" +package.version = "1.4.0-rc.1" package.license = "AGPL-3.0-only OR LicenseRef-Element-Commercial" package.authors = ["Element Backend Team"] package.edition = "2024" @@ -34,35 +34,35 @@ broken_intra_doc_links = "deny" [workspace.dependencies] # Workspace crates -mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.4.0-rc.0" } -mas-cli = { path = "./crates/cli/", version = "=1.4.0-rc.0" } -mas-config = { path = "./crates/config/", version = "=1.4.0-rc.0" } -mas-context = { path = "./crates/context/", version = "=1.4.0-rc.0" } -mas-data-model = { path = "./crates/data-model/", version = "=1.4.0-rc.0" } -mas-email = { path = "./crates/email/", version = "=1.4.0-rc.0" } -mas-graphql = { path = "./crates/graphql/", version = "=1.4.0-rc.0" } -mas-handlers = { path = "./crates/handlers/", version = "=1.4.0-rc.0" } -mas-http = { path = "./crates/http/", version = "=1.4.0-rc.0" } -mas-i18n = { path = "./crates/i18n/", version = "=1.4.0-rc.0" } -mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.4.0-rc.0" } -mas-iana = { path = "./crates/iana/", version = "=1.4.0-rc.0" } -mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.4.0-rc.0" } -mas-jose = { path = "./crates/jose/", version = "=1.4.0-rc.0" } -mas-keystore = { path = "./crates/keystore/", version = "=1.4.0-rc.0" } -mas-listener = { path = "./crates/listener/", version = "=1.4.0-rc.0" } -mas-matrix = { path = "./crates/matrix/", version = "=1.4.0-rc.0" } -mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.4.0-rc.0" } -mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.4.0-rc.0" } -mas-policy = { path = "./crates/policy/", version = "=1.4.0-rc.0" } -mas-router = { path = "./crates/router/", version = "=1.4.0-rc.0" } -mas-spa = { path = "./crates/spa/", version = "=1.4.0-rc.0" } -mas-storage = { path = "./crates/storage/", version = "=1.4.0-rc.0" } -mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.4.0-rc.0" } -mas-tasks = { path = "./crates/tasks/", version = "=1.4.0-rc.0" } -mas-templates = { path = "./crates/templates/", version = "=1.4.0-rc.0" } -mas-tower = { path = "./crates/tower/", version = "=1.4.0-rc.0" } -oauth2-types = { path = "./crates/oauth2-types/", version = "=1.4.0-rc.0" } -syn2mas = { path = "./crates/syn2mas", version = "=1.4.0-rc.0" } +mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.4.0-rc.1" } +mas-cli = { path = "./crates/cli/", version = "=1.4.0-rc.1" } +mas-config = { path = "./crates/config/", version = "=1.4.0-rc.1" } +mas-context = { path = "./crates/context/", version = "=1.4.0-rc.1" } +mas-data-model = { path = "./crates/data-model/", version = "=1.4.0-rc.1" } +mas-email = { path = "./crates/email/", version = "=1.4.0-rc.1" } +mas-graphql = { path = "./crates/graphql/", version = "=1.4.0-rc.1" } +mas-handlers = { path = "./crates/handlers/", version = "=1.4.0-rc.1" } +mas-http = { path = "./crates/http/", version = "=1.4.0-rc.1" } +mas-i18n = { path = "./crates/i18n/", version = "=1.4.0-rc.1" } +mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.4.0-rc.1" } +mas-iana = { path = "./crates/iana/", version = "=1.4.0-rc.1" } +mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.4.0-rc.1" } +mas-jose = { path = "./crates/jose/", version = "=1.4.0-rc.1" } +mas-keystore = { path = "./crates/keystore/", version = "=1.4.0-rc.1" } +mas-listener = { path = "./crates/listener/", version = "=1.4.0-rc.1" } +mas-matrix = { path = "./crates/matrix/", version = "=1.4.0-rc.1" } +mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.4.0-rc.1" } +mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.4.0-rc.1" } +mas-policy = { path = "./crates/policy/", version = "=1.4.0-rc.1" } +mas-router = { path = "./crates/router/", version = "=1.4.0-rc.1" } +mas-spa = { path = "./crates/spa/", version = "=1.4.0-rc.1" } +mas-storage = { path = "./crates/storage/", version = "=1.4.0-rc.1" } +mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.4.0-rc.1" } +mas-tasks = { path = "./crates/tasks/", version = "=1.4.0-rc.1" } +mas-templates = { path = "./crates/templates/", version = "=1.4.0-rc.1" } +mas-tower = { path = "./crates/tower/", version = "=1.4.0-rc.1" } +oauth2-types = { path = "./crates/oauth2-types/", version = "=1.4.0-rc.1" } +syn2mas = { path = "./crates/syn2mas", version = "=1.4.0-rc.1" } # OpenAPI schema generation and validation [workspace.dependencies.aide] diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 5df40da83..9c1121cca 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -149,12 +149,14 @@ async fn try_main() -> anyhow::Result { // Setup OpenTelemetry tracing and metrics self::telemetry::setup(&telemetry_config).context("failed to setup OpenTelemetry")?; - let telemetry_layer = self::telemetry::TRACER.get().map(|tracer| { - tracing_opentelemetry::layer() - .with_tracer(tracer.clone()) - .with_tracked_inactivity(false) - .with_filter(LevelFilter::INFO) - }); + let tracer = self::telemetry::TRACER + .get() + .context("TRACER was not set")?; + + let telemetry_layer = tracing_opentelemetry::layer() + .with_tracer(tracer.clone()) + .with_tracked_inactivity(false) + .with_filter(LevelFilter::INFO); let subscriber = Registry::default() .with(suppress_layer) diff --git a/crates/cli/src/telemetry.rs b/crates/cli/src/telemetry.rs index 274ae770e..54222c8be 100644 --- a/crates/cli/src/telemetry.rs +++ b/crates/cli/src/telemetry.rs @@ -29,11 +29,11 @@ use opentelemetry_sdk::{ metrics::{ManualReader, SdkMeterProvider, periodic_reader_with_async_runtime::PeriodicReader}, propagation::{BaggagePropagator, TraceContextPropagator}, trace::{ - Sampler, SdkTracerProvider, Tracer, span_processor_with_async_runtime::BatchSpanProcessor, + IdGenerator, Sampler, SdkTracerProvider, Tracer, + span_processor_with_async_runtime::BatchSpanProcessor, }, }; use opentelemetry_semantic_conventions as semcov; -use url::Url; static SCOPE: LazyLock = LazyLock::new(|| { InstrumentationScope::builder(env!("CARGO_PKG_NAME")) @@ -94,50 +94,65 @@ fn propagator(propagators: &[Propagator]) -> TextMapCompositePropagator { TextMapCompositePropagator::new(propagators) } -fn stdout_tracer_provider() -> SdkTracerProvider { - let exporter = opentelemetry_stdout::SpanExporter::default(); - SdkTracerProvider::builder() - .with_simple_exporter(exporter) - .build() -} - -fn otlp_tracer_provider( - endpoint: Option<&Url>, - sample_rate: f64, -) -> anyhow::Result { - let mut exporter = opentelemetry_otlp::SpanExporter::builder() - .with_http() - .with_http_client(mas_http::reqwest_client()); - if let Some(endpoint) = endpoint { - exporter = exporter.with_endpoint(endpoint.to_string()); +/// An [`IdGenerator`] which always returns an invalid trace ID and span ID +/// +/// This is used when no exporter is being used, so that we don't log the trace +/// ID when we're not tracing. +#[derive(Debug, Clone, Copy)] +struct InvalidIdGenerator; +impl IdGenerator for InvalidIdGenerator { + fn new_trace_id(&self) -> opentelemetry::TraceId { + opentelemetry::TraceId::INVALID } - let exporter = exporter - .build() - .context("Failed to configure OTLP trace exporter")?; + fn new_span_id(&self) -> opentelemetry::SpanId { + opentelemetry::SpanId::INVALID + } +} - let batch_processor = - BatchSpanProcessor::builder(exporter, opentelemetry_sdk::runtime::Tokio).build(); +fn init_tracer(config: &TracingConfig) -> anyhow::Result<()> { + let sample_rate = config.sample_rate.unwrap_or(1.0); // We sample traces based on the parent if we have one, and if not, we // sample a ratio based on the configured sample rate let sampler = Sampler::ParentBased(Box::new(Sampler::TraceIdRatioBased(sample_rate))); - let tracer_provider = SdkTracerProvider::builder() - .with_span_processor(batch_processor) + let tracer_provider_builder = SdkTracerProvider::builder() .with_resource(resource()) - .with_sampler(sampler) - .build(); + .with_sampler(sampler); - Ok(tracer_provider) -} - -fn init_tracer(config: &TracingConfig) -> anyhow::Result<()> { - let sample_rate = config.sample_rate.unwrap_or(1.0); let tracer_provider = match config.exporter { - TracingExporterKind::None => return Ok(()), - TracingExporterKind::Stdout => stdout_tracer_provider(), - TracingExporterKind::Otlp => otlp_tracer_provider(config.endpoint.as_ref(), sample_rate)?, + TracingExporterKind::None => tracer_provider_builder + .with_id_generator(InvalidIdGenerator) + .with_sampler(Sampler::AlwaysOff) + .build(), + + TracingExporterKind::Stdout => { + let exporter = opentelemetry_stdout::SpanExporter::default(); + tracer_provider_builder + .with_simple_exporter(exporter) + .build() + } + + TracingExporterKind::Otlp => { + let mut exporter = opentelemetry_otlp::SpanExporter::builder() + .with_http() + .with_http_client(mas_http::reqwest_client()); + if let Some(endpoint) = &config.endpoint { + exporter = exporter.with_endpoint(endpoint.as_str()); + } + let exporter = exporter + .build() + .context("Failed to configure OTLP trace exporter")?; + + let batch_processor = + BatchSpanProcessor::builder(exporter, opentelemetry_sdk::runtime::Tokio).build(); + + tracer_provider_builder + .with_span_processor(batch_processor) + .build() + } }; + TRACER_PROVIDER .set(tracer_provider.clone()) .map_err(|_| anyhow::anyhow!("TRACER_PROVIDER was set twice"))?; diff --git a/frontend/.storybook/locales.ts b/frontend/.storybook/locales.ts index 090812bf0..1d023ac3c 100644 --- a/frontend/.storybook/locales.ts +++ b/frontend/.storybook/locales.ts @@ -27,7 +27,7 @@ export type LocalazyMetadata = { }; const localazyMetadata: LocalazyMetadata = { - projectUrl: "https://localazy.com/p/matrix-authentication-service", + projectUrl: "https://localazy.com/p/matrix-authentication-service!v1.4", baseLocale: "en", languages: [ { @@ -172,21 +172,21 @@ const localazyMetadata: LocalazyMetadata = { file: "frontend.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/cs/frontend.json", - "da": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/da/frontend.json", - "de": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/de/frontend.json", - "en": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/en/frontend.json", - "et": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/et/frontend.json", - "fi": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fi/frontend.json", - "fr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fr/frontend.json", - "hu": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/hu/frontend.json", - "nb_NO": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nb-NO/frontend.json", - "nl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nl/frontend.json", - "pt": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt/frontend.json", - "ru": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/ru/frontend.json", - "sv": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sv/frontend.json", - "uk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uk/frontend.json", - "zh#Hans": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/zh-Hans/frontend.json" + "cs": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/cs/frontend.json", + "da": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/da/frontend.json", + "de": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/de/frontend.json", + "en": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/en/frontend.json", + "et": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/et/frontend.json", + "fi": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fi/frontend.json", + "fr": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fr/frontend.json", + "hu": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/hu/frontend.json", + "nb_NO": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nb-NO/frontend.json", + "nl": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nl/frontend.json", + "pt": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt/frontend.json", + "ru": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/ru/frontend.json", + "sv": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sv/frontend.json", + "uk": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uk/frontend.json", + "zh#Hans": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/zh-Hans/frontend.json" } }, { @@ -194,21 +194,21 @@ const localazyMetadata: LocalazyMetadata = { file: "file.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/cs/file.json", - "da": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/da/file.json", - "de": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/de/file.json", - "en": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/en/file.json", - "et": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/et/file.json", - "fi": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fi/file.json", - "fr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fr/file.json", - "hu": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/hu/file.json", - "nb_NO": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nb-NO/file.json", - "nl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nl/file.json", - "pt": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt/file.json", - "ru": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/ru/file.json", - "sv": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sv/file.json", - "uk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uk/file.json", - "zh#Hans": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/zh-Hans/file.json" + "cs": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/cs/file.json", + "da": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/da/file.json", + "de": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/de/file.json", + "en": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/en/file.json", + "et": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/et/file.json", + "fi": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fi/file.json", + "fr": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fr/file.json", + "hu": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/hu/file.json", + "nb_NO": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nb-NO/file.json", + "nl": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nl/file.json", + "pt": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt/file.json", + "ru": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/ru/file.json", + "sv": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sv/file.json", + "uk": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uk/file.json", + "zh#Hans": "https://delivery.localazy.com/_a67795344161040591746e127742/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/zh-Hans/file.json" } } ] diff --git a/translations/nb-NO.json b/translations/nb-NO.json index cca152e38..69b18514f 100644 --- a/translations/nb-NO.json +++ b/translations/nb-NO.json @@ -210,6 +210,7 @@ "register": { "call_to_login": "Har du allerede en konto?", "continue_with_email": "Fortsett med e-postadresse", + "continue_with_password": "Fortsett med passord", "create_account": { "description": "Velg et brukernavn for å fortsette.", "heading": "Opprett en konto"