mirror of https://github.com/abpframework/abp.git
65 changed files with 563 additions and 164 deletions
@ -0,0 +1,15 @@ |
|||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.Web.Security; |
||||
|
|
||||
|
public delegate void ApplicationConfigurationChangedHandler(); |
||||
|
|
||||
|
public class ApplicationConfigurationChangedService : IScopedDependency |
||||
|
{ |
||||
|
public event ApplicationConfigurationChangedHandler Changed; |
||||
|
|
||||
|
public void NotifyChanged() |
||||
|
{ |
||||
|
Changed?.Invoke(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
using System; |
||||
|
using System.Text.Json; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace Volo.Abp.Json.SystemTextJson.JsonConverters; |
||||
|
|
||||
|
public class AbpNullableStringToGuidConverter : JsonConverter<Guid?> |
||||
|
{ |
||||
|
private JsonSerializerOptions _writeJsonSerializerOptions; |
||||
|
|
||||
|
public override Guid? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
||||
|
{ |
||||
|
if (reader.TokenType == JsonTokenType.String) |
||||
|
{ |
||||
|
var guidString = reader.GetString(); |
||||
|
string[] formats = { "N", "D", "B", "P", "X" }; |
||||
|
foreach (var format in formats) |
||||
|
{ |
||||
|
if (Guid.TryParseExact(guidString, format, out var guid)) |
||||
|
{ |
||||
|
return guid; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (reader.TryGetGuid(out var guid2)) |
||||
|
{ |
||||
|
return guid2; |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public override void Write(Utf8JsonWriter writer, Guid? value, JsonSerializerOptions options) |
||||
|
{ |
||||
|
_writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this); |
||||
|
var entityConverter = (JsonConverter<Guid?>)_writeJsonSerializerOptions.GetConverter(typeof(Guid?)); |
||||
|
|
||||
|
entityConverter.Write(writer, value, _writeJsonSerializerOptions); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
using System; |
||||
|
using System.Text.Json; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace Volo.Abp.Json.SystemTextJson.JsonConverters; |
||||
|
|
||||
|
public class AbpStringToGuidConverter : JsonConverter<Guid> |
||||
|
{ |
||||
|
private JsonSerializerOptions _writeJsonSerializerOptions; |
||||
|
|
||||
|
public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
||||
|
{ |
||||
|
if (reader.TokenType == JsonTokenType.String) |
||||
|
{ |
||||
|
var guidString = reader.GetString(); |
||||
|
string[] formats = { "N", "D", "B", "P", "X" }; |
||||
|
foreach (var format in formats) |
||||
|
{ |
||||
|
if (Guid.TryParseExact(guidString, format, out var guid)) |
||||
|
{ |
||||
|
return guid; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return reader.GetGuid(); |
||||
|
} |
||||
|
|
||||
|
public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options) |
||||
|
{ |
||||
|
_writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, this); |
||||
|
var entityConverter = (JsonConverter<Guid>)_writeJsonSerializerOptions.GetConverter(typeof(Guid)); |
||||
|
|
||||
|
entityConverter.Write(writer, value, _writeJsonSerializerOptions); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,85 @@ |
|||||
|
using System; |
||||
|
using System.Text.Json; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Json.SystemTextJson.JsonConverters; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Json; |
||||
|
|
||||
|
public class AbpStringToGuid_Tests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Test_Read() |
||||
|
{ |
||||
|
var options = new JsonSerializerOptions() |
||||
|
{ |
||||
|
Converters = |
||||
|
{ |
||||
|
new AbpStringToGuidConverter(), |
||||
|
new AbpNullableStringToGuidConverter() |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var guid = Guid.Parse("762DDB84-5225-4853-A566-FF0B3AF57585"); |
||||
|
var testClass = JsonSerializer.Deserialize<TestClass>("{" + |
||||
|
$"\"Id\": \"{guid:N}\", " + |
||||
|
$"\"NullableId\": \"{guid:D}\", " + |
||||
|
$"\"NullableId2\": \"{guid:B}\", " + |
||||
|
$"\"NullableId3\": \"{guid:P}\", " + |
||||
|
$"\"NullableId4\": \"{guid:X}\", " + |
||||
|
"\"NullableId5\": \"\", " + |
||||
|
"\"NullableId6\": null}", options); |
||||
|
testClass.ShouldNotBeNull(); |
||||
|
testClass.Id.ShouldBe(guid); |
||||
|
testClass.NullableId.ShouldBe(guid); |
||||
|
testClass.NullableId2.ShouldBe(guid); |
||||
|
testClass.NullableId3.ShouldBe(guid); |
||||
|
testClass.NullableId4.ShouldBe(guid); |
||||
|
testClass.NullableId5.ShouldBeNull(); |
||||
|
testClass.NullableId6.ShouldBeNull(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Test_Write() |
||||
|
{ |
||||
|
var options = new JsonSerializerOptions() |
||||
|
{ |
||||
|
Converters = |
||||
|
{ |
||||
|
new AbpStringToGuidConverter(), |
||||
|
new AbpNullableStringToGuidConverter() |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var guid = Guid.Parse("762DDB84-5225-4853-A566-FF0B3AF57585"); |
||||
|
var json = JsonSerializer.Serialize(new TestClass() |
||||
|
{ |
||||
|
Id = guid, |
||||
|
NullableId = null, |
||||
|
NullableId2 = guid, |
||||
|
NullableId3 = null, |
||||
|
NullableId4 = guid, |
||||
|
NullableId5 = null, |
||||
|
NullableId6 = guid |
||||
|
}, options); |
||||
|
|
||||
|
json.ShouldBe($"{{\"Id\":\"{guid:D}\",\"NullableId\":null,\"NullableId2\":\"{guid:D}\",\"NullableId3\":null,\"NullableId4\":\"{guid:D}\",\"NullableId5\":null,\"NullableId6\":\"{guid:D}\"}}"); |
||||
|
} |
||||
|
|
||||
|
class TestClass |
||||
|
{ |
||||
|
public Guid Id { get; set; } |
||||
|
|
||||
|
public Guid? NullableId { get; set; } |
||||
|
|
||||
|
public Guid? NullableId2 { get; set; } |
||||
|
|
||||
|
public Guid? NullableId3 { get; set; } |
||||
|
|
||||
|
public Guid? NullableId4 { get; set; } |
||||
|
|
||||
|
public Guid? NullableId5 { get; set; } |
||||
|
|
||||
|
public Guid? NullableId6 { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -1,7 +1,18 @@ |
|||||
@page "/authentication/{action}" |
@page "/authentication/{action}" |
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication |
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication |
||||
<RemoteAuthenticatorView Action="@Action" /> |
@using Volo.Abp.AspNetCore.Components.Web.Security |
||||
|
<RemoteAuthenticatorView Action="@Action" OnLogInSucceeded="OnLogInSucceeded" OnLogOutSucceeded="OnLogOutSucceeded" /> |
||||
|
@inject WebAssemblyCachedApplicationConfigurationClient WebAssemblyCachedApplicationConfigurationClient |
||||
@code{ |
@code{ |
||||
[Parameter] public string Action { get; set; } |
[Parameter] public string Action { get; set; } |
||||
|
|
||||
|
private async Task OnLogInSucceeded(RemoteAuthenticationState state) |
||||
|
{ |
||||
|
await WebAssemblyCachedApplicationConfigurationClient.InitializeAsync(); |
||||
|
} |
||||
|
|
||||
|
private async Task OnLogOutSucceeded(RemoteAuthenticationState state) |
||||
|
{ |
||||
|
await WebAssemblyCachedApplicationConfigurationClient.InitializeAsync(); |
||||
|
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,30 @@ |
|||||
|
import { HttpClient, HttpContext, HttpRequest } from '@angular/common/http'; |
||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { Observable } from 'rxjs'; |
||||
|
import { IS_EXTERNAL_REQUEST } from '../tokens/http-context.token'; |
||||
|
|
||||
|
// source : https://github.com/armanozak/demo-angular-server-specific-interceptors
|
||||
|
@Injectable({ |
||||
|
providedIn: 'root', |
||||
|
}) |
||||
|
export class ExternalHttpClient extends HttpClient { |
||||
|
override request( |
||||
|
first: string | HttpRequest<any>, |
||||
|
url?: string, |
||||
|
options: RequestOptions = {}, |
||||
|
): Observable<any> { |
||||
|
if (typeof first === 'string') { |
||||
|
this.#setPlaceholderContext(options); |
||||
|
return super.request(first, url, options); |
||||
|
} |
||||
|
|
||||
|
this.#setPlaceholderContext(first); |
||||
|
return super.request(first); |
||||
|
} |
||||
|
#setPlaceholderContext(optionsOrRequest: { context?: HttpContext }) { |
||||
|
optionsOrRequest.context ??= new HttpContext(); |
||||
|
optionsOrRequest.context.set(IS_EXTERNAL_REQUEST, true); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
type RequestOptions = Parameters<HttpClient['request']>[2]; |
||||
@ -0,0 +1 @@ |
|||||
|
export * from './http.client'; |
||||
@ -1,8 +1,7 @@ |
|||||
import { Provider } from "@angular/core"; |
import { Provider } from '@angular/core'; |
||||
import { INCUDE_LOCALIZATION_RESOURCES_TOKEN } from "../tokens/include-localization-resources.token"; |
import { INCUDE_LOCALIZATION_RESOURCES_TOKEN } from '../tokens/include-localization-resources.token'; |
||||
|
|
||||
export const IncludeLocalizationResourcesProvider: Provider = { |
export const IncludeLocalizationResourcesProvider: Provider = { |
||||
provide: INCUDE_LOCALIZATION_RESOURCES_TOKEN, |
provide: INCUDE_LOCALIZATION_RESOURCES_TOKEN, |
||||
useValue: false, |
useValue: false, |
||||
}; |
}; |
||||
|
|
||||
|
|||||
@ -1,3 +1,3 @@ |
|||||
export * from './cookie-language.provider'; |
export * from './cookie-language.provider'; |
||||
export * from './locale.provider'; |
export * from './locale.provider'; |
||||
export * from './include-localization-resources.provider'; |
export * from './include-localization-resources.provider'; |
||||
|
|||||
@ -0,0 +1,17 @@ |
|||||
|
export const APPLICATION_LOCALIZATION_DATA = { |
||||
|
resources: { |
||||
|
Default: { texts: {}, baseResources: [] }, |
||||
|
MyProjectName: { |
||||
|
texts: { |
||||
|
"'{0}' and '{1}' do not match.": "'{0}' and '{1}' do not match.", |
||||
|
}, |
||||
|
baseResources: [], |
||||
|
}, |
||||
|
AbpIdentity: { |
||||
|
texts: { |
||||
|
Identity: 'identity', |
||||
|
}, |
||||
|
baseResources: [], |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
@ -0,0 +1,3 @@ |
|||||
|
import { HttpContextToken } from '@angular/common/http'; |
||||
|
|
||||
|
export const IS_EXTERNAL_REQUEST = new HttpContextToken<boolean>(() => false); |
||||
@ -1,3 +1,5 @@ |
|||||
import { InjectionToken } from "@angular/core"; |
import { InjectionToken } from '@angular/core'; |
||||
|
|
||||
export const INCUDE_LOCALIZATION_RESOURCES_TOKEN = new InjectionToken<boolean>('INCUDE_LOCALIZATION_RESOURCES_TOKEN'); |
export const INCUDE_LOCALIZATION_RESOURCES_TOKEN = new InjectionToken<boolean>( |
||||
|
'INCUDE_LOCALIZATION_RESOURCES_TOKEN', |
||||
|
); |
||||
|
|||||
@ -1,6 +1,9 @@ |
|||||
import { InjectionToken } from '@angular/core'; |
import { InjectionToken } from '@angular/core'; |
||||
import { SetTokenResponseToStorageFn } from '../models'; |
import { SetTokenResponseToStorageFn } from '../models'; |
||||
|
|
||||
|
/** |
||||
|
* @deprecated The token should not be used anymore. |
||||
|
*/ |
||||
export const SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY = new InjectionToken<SetTokenResponseToStorageFn>( |
export const SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY = new InjectionToken<SetTokenResponseToStorageFn>( |
||||
'SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY', |
'SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY', |
||||
); |
); |
||||
|
|||||
Loading…
Reference in new issue