Experiencing error <asynchronous suspension> in project - flutter-dependencies

Future<void> shareFile() async {
await getImage();
Directory? directory = await getExternalStorageDirectory();
print('${directory!.path} / ${_image!.path}');
await WhatsappShare.shareFile(
phone: _phone,
filePath: ["${_image!.path}"],
);
}
Future getImage() async {
try {
final ImagePicker _picker = ImagePicker();
XFile? _pickedFile =
(await _picker.pickImage(source: ImageSource.gallery));
if (_pickedFile != null) {
// getting a directory path for saving
final directory = await getExternalStorageDirectory();
// copy the file to a new path
await _pickedFile.saveTo('${directory!.path}/image1.png');
_image = File('${directory.path}/image1.png');
}
} catch (er) {
print(er);
}
}
When using the Whatsapp_share2 dependencies experiencing the error of . I'm beginner of flutter. Please help to solve the error in above code.
Can anyone help me to resolve this issue

Related

How to create a .pdf or .csv file automatically in React Native for Android 11 (or later)

The following code works up to Android 10, it is creating a csv file in the DCIM folder:
import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';
export async function saveCSV() {
const permission = await MediaLibrary.requestPermissionsAsync();
if (permission.status != 'granted') {
console.log("Permission not Granted!")
return;
}
// CSVLocation
const directoryUri = FileSystem.documentDirectory;
const fileUri = directoryUri + `formData.csv`;
// Save to DCIM folder
const asset = await MediaLibrary.createAssetAsync(fileUri);
try {
const album = await MediaLibrary.getAlbumAsync('album');
if (album == null) {
console.log("ASSET", asset)
await MediaLibrary.createAlbumAsync('album', asset, true);
} else {
await MediaLibrary.addAssetsToAlbumAsync([asset], album, true)
.then(() => {
console.log('File Saved Successfully!');
})
.catch((err: string) => {
console.log('Error In Saving File!', err);
});
}
} catch (e) {
console.log(e);
}
}
Previously this line of code was executed in another function to create a file in the fileUri used above:
await FileSystem.writeAsStringAsync(fileUri, CSVheader + newInfo);
This issue has been described here: https://github.com/expo/expo/issues/12060
In short: Expo Media library is able to save image/video/audio assets so it will fail with other file types. Weirdly enough it was working fine with .pdf and .csv up to Android 10.
In the link above, and also on stackoverflow there are solutions using StorageAccessFramework. However, the user needs to create a subdirectory inside Downloads every time a file needs to be saved. I would like to make it automatically without any popups (after permission is granted).
The destination folder doesn't matter as long as it is accessible by the user later.

I am converting Images to pdf using a npm library in react native why it is giving error of null object?

I am using react-native-image-to-pdf library to convert images to pdf in my react native app. from https://www.npmjs.com/package/react-native-image-to-pdf
var photoPath = ['https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350','https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350'];
const myAsyncPDFFunction = async () => {
try {
const options = {
imagePaths: photoPath,
name: 'PDFName',
};
const pdf = await RNImageToPdf.createPDFbyImages(options);
console.log(pdf.filePath);
} catch(e) {
console.log(e);
}
}
but this is giving error Error: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
I have also tried giving path as ['./assets/a.png', './assets/b.png']
but still getting same error
Based on the usage example, your photoPath needs to be a local file path and not a remote path.
My recommendation is to first use rn-fetch-blob to download the remote image to the device, and then pass your new local image path to react-native-image-to-pdf. Something like:
RNFetchBlob
.config({
// add this option that makes response data to be stored as a file,
// this is much more performant.
fileCache : true,
})
.fetch('GET', 'http://www.example.com/file/example.png', {
//some headers ..
})
.then(async (res) => {
// the temp file path
console.log('The file saved to ', res.path())
const options = {
imagePaths: [res.path()],
name: 'PDFName',
};
const pdf = await RNImageToPdf.createPDFbyImages(options);
})
from file path remove the text 'file://; with empty string('').
const options = {
imagePaths: [uri.replace('file://', '')],
name: 'FileName',
quality: .9, // optional compression paramter
};
replace('file://', '') it's work for me

AWS SDK 3 WriteGetObjectResponseCommand issue

On my current project we are trying to migrate to AWS SDK version 3 (Javascript). We are using s3 object lambdas and have faced and issue with WriteGetObjectResponseCommand command.
WriteGetObjectResponseCommand code:
import { S3Client, S3 } from '#aws-sdk/client-s3';
const s3Client = new S3Client({});
async function passTransformedPhoto(
body: Buffer,
outputRoute: string,
outputToken: string,
): Promise<WriteGetObjectResponseCommandOutput> {
try {
const writeGetObjectParams: WriteGetObjectResponseCommandInput = {
RequestRoute: outputRoute,
RequestToken: outputToken,
Body: body,
};
const command = new WriteGetObjectResponseCommand(writeGetObjectParams);
return s3Client.send(command);
} catch (e) {
console.log('Error happens in passTransformedPhoto', e);
}
The same issue with the aggregated client:
import { S3Client, S3 } from '#aws-sdk/client-s3';
const s3Aggregated = new S3({});
async function passTransformedPhoto(body: Buffer, outputRoute: string, outputToken: string) {
try {
const result = await s3Aggregated.writeGetObjectResponse({
RequestRoute: outputRoute,
RequestToken: outputToken,
Body: body,
});
return result;
} catch (e) {
console.log('Error happens in passTransformedPhoto', e);
}
}
Error:
INFO TypeError: Cannot destructure property 'service' of 'bucketName' as it is undefined.
at getEndpointFromArn (/var/task/node_modules/#aws-sdk/middleware-bucket-endpoint/dist/cjs/bucketHostname.js:26:13)
at Object.bucketHostname (/var/task/node_modules/#aws-sdk/middleware-bucket-endpoint/dist/cjs/bucketHostname.js:17:13)
at /var/task/node_modules/#aws-sdk/middleware-bucket-endpoint/dist/cjs/bucketEndpointMiddleware.js:47:67
at processTicksAndRejections (internal/process/task_queues.js:95:5)
Environment:
#aws-sdk/client-s3: 3.18.0
Node.js: v 14.17.0
typescript: 4.3.2
Any help or clarification on this issue is much appreciated.
Maybe try including all the expected S3Client config options:
const config = {
region: <region>,
bucketEndpoint: true,
}
const client = new S3Client(config);

DocumentPicker in React-Native not working properly for Android devices

I have implemented a document picker in my react native application and it is working fine for iOS. However in Android, I am having a weird issue
When I open the document picker and the navigation takes to the file explorer (Downloads section) in Android phone, though I am able to select the pdf file but, when it comes to the application back, it stuck to the page and the file is not there. I have attached the screenshot Same behaviour when the file explorer takes to the recent files. Only when from the recent files, I select the google drive and try to select the pdf from there, it works as expected and I can see the file in my application and the app do not stuck.
Here is what I have written for the pdf document picker
selectPDF = async ()=>{
var imageList = [...this.state.files];
try {
const results = await DocumentPicker.pickMultiple({
type: [DocumentPicker.types.pdf],
});
for (const res of results) {
console.log(
res.uri,
res.type, // mime type
res.name,
res.size
);
const fileName = res.uri.replace("file://","");
let data1 = ''
RnFetchBlob.fs.readStream(
fileName,
'base64',
4095
)
.then((ifstream)=>{
//let data1 = ''
ifstream.open()
ifstream.onData((data)=>{
data1 += data;
})
ifstream.onEnd(() => {
let base64 = data1
imageList.push({
imageName:res.name,
image:base64,
mime:res.type,
size:res.size
})
this.setState({
...this.state,
openCamera:false,
lastFileName:imageList[imageList.length - 1].imageName,
files:imageList
})
})
})
}
} catch (err) {
if (DocumentPicker.isCancel(err)) {
this.closeModal();
} else {
throw err;
}
}
}
Can anyone throw some light as to what I may be missing. Is some configuration needs to be set on device level or any other thing.
you can use something like this,
const [file, setFile] = useState(null);
const selectFile = async () => {
try {
const results = await DocumentPicker.pickMultiple({
type: [DocumentPicker.types.allFiles],
});
setFile(results);
} catch (err) {
if (DocumentPicker.isCancel(err)) {
alert('Canceled');
} else {
alert('Unknown Error: ' + JSON.stringify(err));
throw err;
}
}
};
now you can call file in your function
and to use it you can do like this
<TouchableOpacity
activeOpacity={0.5}
onPress={selectFile}>
<Text>Select File</Text>
</TouchableOpacity>

Standalone Blazor WebAssembly authentication very slow [duplicate]

I would like to set up a Blazor client-side app with authentication through AWS Cognito.
When I run the app I'm not redirected to a login page, instead the page says "Authorizing..." for a few seconds, while I get this error in the console:
The loading of “https://blazorapp.auth.eu-central-1.amazoncognito.com/login?…Q&code_challenge_method=S256&prompt=none&response_mode=query” in a frame is denied by “X-Frame-Options“ directive set to “DENY“.
This error page has no error code in its security info
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed.
Then, the default "Hello, world!" index page is shown (even though as I understand it, it should not be visible to an unauthenticated user based on App.razor definition?). If I click on "Log in", I get the same error in console, but then after a few seconds the Cognito-hosted login page opens, I am able to log in, I am redirected back to my app, and the app shows the authenticated user's info in top right corner, but the console is a little weird again:
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed.
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
Authorization was successful.
Question 1
How can I get rid of these errors and have my app redirect to Cognito login page without ~10s delay?
Question 2
Why is all content in my app visible at all times regardless of whether I'm authenticated or not? It's as if the NotAuthorized node under AuthorizeRouteView in App.razor had no effect at all, unless I am confusing something here
Code:
Program.cs
builder.Services.AddOidcAuthentication(options =>
{
options.ProviderOptions.Authority = "https://cognito-idp.{aws-region}.amazonaws.com/{cognito-userpoolid}";
options.ProviderOptions.ClientId = "{cognito-clientid}";
options.ProviderOptions.ResponseType = "code";
options.ProviderOptions.RedirectUri = "https://localhost:44306/authentication/login-callback";
options.ProviderOptions.PostLogoutRedirectUri = "https://localhost:44306/authentication/logout-callback";
});
App.razor (as created from template, no modifications)
<CascadingAuthenticationState>
<Router AppAssembly="#typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="#routeData" DefaultLayout="#typeof(MainLayout)">
<NotAuthorized>
#if (!context.User.Identity.IsAuthenticated)
{
<RedirectToLogin />
}
else
{
<p>You are not authorized to access this resource.</p>
}
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="#typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
I have only modified the call to AddOidcAuthentication in Program.cs myself, all other files were populated by Visual Studio when creating a Blazor WebAssembly App with Individual User Accounts.
I am struggling to get this to work and would greatly appreciate any help on this topic
EDIT:
Following #aguafrommars's answer I have published the website to Amazon S3 using static website hosting with Amazon CloudFront as CDN, however, the behavior of the published app is exactly the same as described local behavior
To expand on the questions:
Question 1 expanded:
When the page says "Authorizing..." I only get the described error in the console, the Cognito hosted UI is not rendered, only when I click on "Log in" I am either redirected (with major delay) to Cognito hosted UI, or authenticated without redirection (if I signed in before), perhaps this GIF will clear things up:
I might be wrong, but isn't the problem that the Cognito hosted UI is rejecting to be rendered in an iframe? Can my app redirect to the hosted UI in the first place, like it eventually does? Right now I have to wait while X-Frame-Options error is thrown, click on "Log in", wait while another X-Frame-Options error is thrown, and then finally I'm redirected and the flow succeeds (in the gif the UI doesn't show up because I authenticated before in the session)
Question 2 expanded:
The behavior I want to achieve is that if the user is not authenticated, they cannot see any part of the application, instead they are redirected to Cognito hosted UI and only after they are authenticated they can see anything. I tried to play around with Authorize attribute in MainLayout.razor, but the result is always a blank screen, I would like to provide some code and details but I believe the behavior is impacted by errors described in Question 1, which is why I would like to sort it out first
I'm answering this issue which was marked as duplicate here...
The reason for the delay is the timeout waiting for the silent login process (which has a 10s timeout I believe) as mentioned here and here
Root cause is that AWS Cognito is not compliant with the OIDC standards. Which results in the "'X-Frame-Options' to 'DENY'" error in the browser console.
Until the Blazor team allow us to turn off the silent signin from code, the solution was to disable silent login as follows:
Download the Blazor Interop files located in the asp.net repo here to a local folder.
Open the local folder using vs code and install typescript, webpack, yarn, etc if not already installed
npm install -g yarn
npm install -g typescript
npm install -g webpack
Then edit the AuthenticationService.ts file as follows (commenting out the silent signin functionality). Sorry for the long code print.
import { UserManager, UserManagerSettings, User } from 'oidc-client'
type Writeable<T> = { -readonly [P in keyof T]: T[P] };
type ExtendedUserManagerSettings = Writeable<UserManagerSettings & AuthorizeServiceSettings>
type OidcAuthorizeServiceSettings = ExtendedUserManagerSettings | ApiAuthorizationSettings;
function isApiAuthorizationSettings(settings: OidcAuthorizeServiceSettings): settings is ApiAuthorizationSettings {
return settings.hasOwnProperty('configurationEndpoint');
}
interface AuthorizeServiceSettings {
defaultScopes: string[];
}
interface ApiAuthorizationSettings {
configurationEndpoint: string;
}
export interface AccessTokenRequestOptions {
scopes: string[];
returnUrl: string;
}
export interface AccessTokenResult {
status: AccessTokenResultStatus;
token?: AccessToken;
}
export interface AccessToken {
value: string;
expires: Date;
grantedScopes: string[];
}
export enum AccessTokenResultStatus {
Success = 'success',
RequiresRedirect = 'requiresRedirect'
}
export enum AuthenticationResultStatus {
Redirect = 'redirect',
Success = 'success',
Failure = 'failure',
OperationCompleted = 'operationCompleted'
};
export interface AuthenticationResult {
status: AuthenticationResultStatus;
state?: unknown;
message?: string;
}
export interface AuthorizeService {
getUser(): Promise<unknown>;
getAccessToken(request?: AccessTokenRequestOptions): Promise<AccessTokenResult>;
signIn(state: unknown): Promise<AuthenticationResult>;
completeSignIn(state: unknown): Promise<AuthenticationResult>;
signOut(state: unknown): Promise<AuthenticationResult>;
completeSignOut(url: string): Promise<AuthenticationResult>;
}
class OidcAuthorizeService implements AuthorizeService {
private _userManager: UserManager;
private _intialSilentSignIn: Promise<void> | undefined;
constructor(userManager: UserManager) {
this._userManager = userManager;
}
async trySilentSignIn() {
if (!this._intialSilentSignIn) {
this._intialSilentSignIn = (async () => {
try {
await this._userManager.signinSilent();
} catch (e) {
// It is ok to swallow the exception here.
// The user might not be logged in and in that case it
// is expected for signinSilent to fail and throw
}
})();
}
return this._intialSilentSignIn;
}
async getUser() {
// if (window.parent === window && !window.opener && !window.frameElement && this._userManager.settings.redirect_uri &&
// !location.href.startsWith(this._userManager.settings.redirect_uri)) {
// // If we are not inside a hidden iframe, try authenticating silently.
// await AuthenticationService.instance.trySilentSignIn();
// }
const user = await this._userManager.getUser();
return user && user.profile;
}
async getAccessToken(request?: AccessTokenRequestOptions): Promise<AccessTokenResult> {
const user = await this._userManager.getUser();
if (hasValidAccessToken(user) && hasAllScopes(request, user.scopes)) {
return {
status: AccessTokenResultStatus.Success,
token: {
grantedScopes: user.scopes,
expires: getExpiration(user.expires_in),
value: user.access_token
}
};
} else {
try {
const parameters = request && request.scopes ?
{ scope: request.scopes.join(' ') } : undefined;
const newUser = await this._userManager.signinSilent(parameters);
return {
status: AccessTokenResultStatus.Success,
token: {
grantedScopes: newUser.scopes,
expires: getExpiration(newUser.expires_in),
value: newUser.access_token
}
};
} catch (e) {
return {
status: AccessTokenResultStatus.RequiresRedirect
};
}
}
function hasValidAccessToken(user: User | null): user is User {
return !!(user && user.access_token && !user.expired && user.scopes);
}
function getExpiration(expiresIn: number) {
const now = new Date();
now.setTime(now.getTime() + expiresIn * 1000);
return now;
}
function hasAllScopes(request: AccessTokenRequestOptions | undefined, currentScopes: string[]) {
const set = new Set(currentScopes);
if (request && request.scopes) {
for (const current of request.scopes) {
if (!set.has(current)) {
return false;
}
}
}
return true;
}
}
async signIn(state: unknown) {
try {
await this._userManager.clearStaleState();
await this._userManager.signinRedirect(this.createArguments(state));
return this.redirect();
} catch (redirectError) {
return this.error(this.getExceptionMessage(redirectError));
}
// try {
// await this._userManager.clearStaleState();
// await this._userManager.signinSilent(this.createArguments());
// return this.success(state);
// } catch (silentError) {
// try {
// await this._userManager.clearStaleState();
// await this._userManager.signinRedirect(this.createArguments(state));
// return this.redirect();
// } catch (redirectError) {
// return this.error(this.getExceptionMessage(redirectError));
// }
// }
}
async completeSignIn(url: string) {
const requiresLogin = await this.loginRequired(url);
const stateExists = await this.stateExists(url);
try {
const user = await this._userManager.signinCallback(url);
if (window.self !== window.top) {
return this.operationCompleted();
} else {
return this.success(user && user.state);
}
} catch (error) {
if (requiresLogin || window.self !== window.top || !stateExists) {
return this.operationCompleted();
}
return this.error('There was an error signing in.');
}
}
async signOut(state: unknown) {
try {
if (!(await this._userManager.metadataService.getEndSessionEndpoint())) {
await this._userManager.removeUser();
return this.success(state);
}
await this._userManager.signoutRedirect(this.createArguments(state));
return this.redirect();
} catch (redirectSignOutError) {
return this.error(this.getExceptionMessage(redirectSignOutError));
}
}
async completeSignOut(url: string) {
try {
if (await this.stateExists(url)) {
const response = await this._userManager.signoutCallback(url);
return this.success(response && response.state);
} else {
return this.operationCompleted();
}
} catch (error) {
return this.error(this.getExceptionMessage(error));
}
}
private getExceptionMessage(error: any) {
if (isOidcError(error)) {
return error.error_description;
} else if (isRegularError(error)) {
return error.message;
} else {
return error.toString();
}
function isOidcError(error: any): error is (Oidc.SigninResponse & Oidc.SignoutResponse) {
return error && error.error_description;
}
function isRegularError(error: any): error is Error {
return error && error.message;
}
}
private async stateExists(url: string) {
const stateParam = new URLSearchParams(new URL(url).search).get('state');
if (stateParam && this._userManager.settings.stateStore) {
return await this._userManager.settings.stateStore.get(stateParam);
} else {
return undefined;
}
}
private async loginRequired(url: string) {
const errorParameter = new URLSearchParams(new URL(url).search).get('error');
if (errorParameter && this._userManager.settings.stateStore) {
const error = await this._userManager.settings.stateStore.get(errorParameter);
return error === 'login_required';
} else {
return false;
}
}
private createArguments(state?: unknown) {
return { useReplaceToNavigate: true, data: state };
}
private error(message: string) {
return { status: AuthenticationResultStatus.Failure, errorMessage: message };
}
private success(state: unknown) {
return { status: AuthenticationResultStatus.Success, state };
}
private redirect() {
return { status: AuthenticationResultStatus.Redirect };
}
private operationCompleted() {
return { status: AuthenticationResultStatus.OperationCompleted };
}
}
export class AuthenticationService {
static _infrastructureKey = 'Microsoft.AspNetCore.Components.WebAssembly.Authentication';
static _initialized: Promise<void>;
static instance: OidcAuthorizeService;
static _pendingOperations: { [key: string]: Promise<AuthenticationResult> | undefined } = {}
public static init(settings: UserManagerSettings & AuthorizeServiceSettings) {
// Multiple initializations can start concurrently and we want to avoid that.
// In order to do so, we create an initialization promise and the first call to init
// tries to initialize the app and sets up a promise other calls can await on.
if (!AuthenticationService._initialized) {
AuthenticationService._initialized = AuthenticationService.initializeCore(settings);
}
return AuthenticationService._initialized;
}
public static handleCallback() {
return AuthenticationService.initializeCore();
}
private static async initializeCore(settings?: UserManagerSettings & AuthorizeServiceSettings) {
const finalSettings = settings || AuthenticationService.resolveCachedSettings();
if (!settings && finalSettings) {
const userManager = AuthenticationService.createUserManagerCore(finalSettings);
if (window.parent !== window && !window.opener && (window.frameElement && userManager.settings.redirect_uri &&
location.href.startsWith(userManager.settings.redirect_uri))) {
// If we are inside a hidden iframe, try completing the sign in early.
// This prevents loading the blazor app inside a hidden iframe, which speeds up the authentication operations
// and avoids wasting resources (CPU and memory from bootstrapping the Blazor app)
AuthenticationService.instance = new OidcAuthorizeService(userManager);
// This makes sure that if the blazor app has time to load inside the hidden iframe,
// it is not able to perform another auth operation until this operation has completed.
AuthenticationService._initialized = (async (): Promise<void> => {
await AuthenticationService.instance.completeSignIn(location.href);
return;
})();
}
} else if (settings) {
const userManager = await AuthenticationService.createUserManager(settings);
AuthenticationService.instance = new OidcAuthorizeService(userManager);
} else {
// HandleCallback gets called unconditionally, so we do nothing for normal paths.
// Cached settings are only used on handling the redirect_uri path and if the settings are not there
// the app will fallback to the default logic for handling the redirect.
}
}
private static resolveCachedSettings(): UserManagerSettings | undefined {
const cachedSettings = window.sessionStorage.getItem(`${AuthenticationService._infrastructureKey}.CachedAuthSettings`);
return cachedSettings ? JSON.parse(cachedSettings) : undefined;
}
public static getUser() {
return AuthenticationService.instance.getUser();
}
public static getAccessToken(options: AccessTokenRequestOptions) {
return AuthenticationService.instance.getAccessToken(options);
}
public static signIn(state: unknown) {
return AuthenticationService.instance.signIn(state);
}
public static async completeSignIn(url: string) {
let operation = this._pendingOperations[url];
if (!operation) {
operation = AuthenticationService.instance.completeSignIn(url);
await operation;
delete this._pendingOperations[url];
}
return operation;
}
public static signOut(state: unknown) {
return AuthenticationService.instance.signOut(state);
}
public static async completeSignOut(url: string) {
let operation = this._pendingOperations[url];
if (!operation) {
operation = AuthenticationService.instance.completeSignOut(url);
await operation;
delete this._pendingOperations[url];
}
return operation;
}
private static async createUserManager(settings: OidcAuthorizeServiceSettings): Promise<UserManager> {
let finalSettings: UserManagerSettings;
if (isApiAuthorizationSettings(settings)) {
const response = await fetch(settings.configurationEndpoint);
if (!response.ok) {
throw new Error(`Could not load settings from '${settings.configurationEndpoint}'`);
}
const downloadedSettings = await response.json();
finalSettings = downloadedSettings;
} else {
if (!settings.scope) {
settings.scope = settings.defaultScopes.join(' ');
}
if (settings.response_type === null) {
// If the response type is not set, it gets serialized as null. OIDC-client behaves differently than when the value is undefined, so we explicitly check for a null value and remove the property instead.
delete settings.response_type;
}
finalSettings = settings;
}
window.sessionStorage.setItem(`${AuthenticationService._infrastructureKey}.CachedAuthSettings`, JSON.stringify(finalSettings));
return AuthenticationService.createUserManagerCore(finalSettings);
}
private static createUserManagerCore(finalSettings: UserManagerSettings) {
const userManager = new UserManager(finalSettings);
userManager.events.addUserSignedOut(async () => {
userManager.removeUser();
});
return userManager;
}
}
declare global {
interface Window { AuthenticationService: AuthenticationService }
}
AuthenticationService.handleCallback();
window.AuthenticationService = AuthenticationService;
Then build the js with
yarn build:release
Once the js file is compiled, copy the AuthenticationService.js file into the/wwwroot directory of your Blazor WASM app.
Then in the index.html file, comment out the MS script and replace with your own:
<!-- <script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>-->
<script src="AuthenticationService.js"></script>
Run your app and Cognito will now be (relatively) instantaneous
I ended up switching from Cognito to Auth0 and upgrading from Api Gateway's RestApi to HttpApi, which includes built in JWT authorizer, and I am very happy with the change. Cognito just had too many problems in the end, but if someone is determined to get it to work check #aguafrommars's comments under the accepted answer.
Response 1:
While the authorizing message is displayed, the app check for a valid authentication and set up auto renew token iframe. If you look at the network log on your browser you'll see requests made by this time.
When the app run in release it's faster.
Response 2:
You need to add authorization on pages you want to protect by adding the Authorize attribute.
#page "/"
#attribute [Authorize]
Had the same problem and switched out to Azure B2C which again resolved the issue. Appears to be a problem with the auth library when linking to AWS Cognito as the auth provider.
Issues raised with MS -
https://github.com/dotnet/aspnetcore/issues/22651