Skip to content

Commit

Permalink
chore: update dependencies of graphql-api (#1135)
Browse files Browse the repository at this point in the history
  • Loading branch information
pradel committed May 6, 2021
1 parent d3662f1 commit 304cc18
Show file tree
Hide file tree
Showing 6 changed files with 1,152 additions and 172 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-forks-deliver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@accounts/graphql-api': patch
---

Upgrade dependencies
3 changes: 2 additions & 1 deletion packages/graphql-api/codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ generates:
noNamespaces: true
noSchemaStitching: true
plugins:
- add: /* eslint-disable */
- add:
content: '/* eslint-disable */'
- typescript
- typescript-resolvers
- typescript-operations
25 changes: 12 additions & 13 deletions packages/graphql-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,28 @@
"graphql-tag": "^2.10.0"
},
"dependencies": {
"@graphql-tools/merge": "6.2.5",
"@graphql-tools/utils": "7.0.2",
"@graphql-tools/merge": "6.2.13",
"@graphql-tools/utils": "7.9.0",
"request-ip": "2.1.3",
"tslib": "2.1.0"
},
"devDependencies": {
"@accounts/password": "^0.32.0",
"@accounts/server": "^0.32.0",
"@accounts/types": "^0.32.0",
"@graphql-codegen/add": "1.17.4",
"@graphql-codegen/cli": "1.17.4",
"@graphql-codegen/introspection": "1.17.4",
"@graphql-codegen/typescript": "1.17.4",
"@graphql-codegen/typescript-operations": "1.17.4",
"@graphql-codegen/typescript-resolvers": "1.17.4",
"@graphql-codegen/typescript-type-graphql": "1.17.4",
"@graphql-codegen/add": "2.0.2",
"@graphql-codegen/cli": "1.21.4",
"@graphql-codegen/introspection": "1.18.2",
"@graphql-codegen/typescript": "1.22.0",
"@graphql-codegen/typescript-operations": "1.17.16",
"@graphql-codegen/typescript-resolvers": "1.19.1",
"@graphql-codegen/typescript-type-graphql": "1.18.4",
"@graphql-modules/core": "0.7.17",
"@types/jest": "25.2.3",
"@types/jest": "26.0.23",
"@types/request-ip": "0.0.35",
"concurrently": "5.2.0",
"graphql": "14.6.0",
"jest": "26.6.3",
"ts-jest": "26.4.4",
"ts-node": "8.10.1"
"ts-jest": "26.5.6",
"ts-node": "9.1.1"
}
}
23 changes: 12 additions & 11 deletions packages/graphql-api/src/models.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/* eslint-disable */
import { GraphQLResolveInfo } from 'graphql';
export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: any }> = { [K in keyof T]: T[K] };
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
export type RequireFields<T, K extends keyof T> = { [X in Exclude<keyof T, K>]?: T[X] } & { [P in K]-?: NonNullable<T[P]> };

/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
Expand Down Expand Up @@ -250,7 +251,7 @@ export type TypeResolveFn<TTypes, TParent = {}, TContext = {}> = (
info: GraphQLResolveInfo
) => Maybe<TTypes> | Promise<Maybe<TTypes>>;

export type IsTypeOfResolverFn<T = {}> = (obj: T, info: GraphQLResolveInfo) => boolean | Promise<boolean>;
export type IsTypeOfResolverFn<T = {}, TContext = {}> = (obj: T, context: TContext, info: GraphQLResolveInfo) => boolean | Promise<boolean>;

export type NextResolverFn<T> = () => Promise<T>;

Expand Down Expand Up @@ -311,27 +312,27 @@ export type AuthDirectiveResolver<Result, Parent, ContextType = any, Args = Auth
export type CreateUserResultResolvers<ContextType = any, ParentType extends ResolversParentTypes['CreateUserResult'] = ResolversParentTypes['CreateUserResult']> = {
userId?: Resolver<Maybe<ResolversTypes['ID']>, ParentType, ContextType>;
loginResult?: Resolver<Maybe<ResolversTypes['LoginResult']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type EmailRecordResolvers<ContextType = any, ParentType extends ResolversParentTypes['EmailRecord'] = ResolversParentTypes['EmailRecord']> = {
address?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
verified?: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type ImpersonateReturnResolvers<ContextType = any, ParentType extends ResolversParentTypes['ImpersonateReturn'] = ResolversParentTypes['ImpersonateReturn']> = {
authorized?: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType>;
tokens?: Resolver<Maybe<ResolversTypes['Tokens']>, ParentType, ContextType>;
user?: Resolver<Maybe<ResolversTypes['User']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type LoginResultResolvers<ContextType = any, ParentType extends ResolversParentTypes['LoginResult'] = ResolversParentTypes['LoginResult']> = {
sessionId?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
tokens?: Resolver<Maybe<ResolversTypes['Tokens']>, ParentType, ContextType>;
user?: Resolver<Maybe<ResolversTypes['User']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type MutationResolvers<ContextType = any, ParentType extends ResolversParentTypes['Mutation'] = ResolversParentTypes['Mutation']> = {
Expand Down Expand Up @@ -359,7 +360,7 @@ export type QueryResolvers<ContextType = any, ParentType extends ResolversParent
export type TokensResolvers<ContextType = any, ParentType extends ResolversParentTypes['Tokens'] = ResolversParentTypes['Tokens']> = {
refreshToken?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
accessToken?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type TwoFactorSecretKeyResolvers<ContextType = any, ParentType extends ResolversParentTypes['TwoFactorSecretKey'] = ResolversParentTypes['TwoFactorSecretKey']> = {
Expand All @@ -371,14 +372,14 @@ export type TwoFactorSecretKeyResolvers<ContextType = any, ParentType extends Re
qr_code_base32?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
google_auth_qr?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
otpauth_url?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type UserResolvers<ContextType = any, ParentType extends ResolversParentTypes['User'] = ResolversParentTypes['User']> = {
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
emails?: Resolver<Maybe<Array<ResolversTypes['EmailRecord']>>, ParentType, ContextType>;
username?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type Resolvers<ContextType = any> = {
Expand Down Expand Up @@ -408,4 +409,4 @@ export type DirectiveResolvers<ContextType = any> = {
* @deprecated
* Use "DirectiveResolvers" root object instead. If you wish to get "IDirectiveResolvers", add "typesPrefix: I" to your config.
*/
export type IDirectiveResolvers<ContextType = any> = DirectiveResolvers<ContextType>;
export type IDirectiveResolvers<ContextType = any> = DirectiveResolvers<ContextType>;
73 changes: 36 additions & 37 deletions website/docs/strategies/oauth.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ npm install @accounts/oauth --save
This example is written in Typescript - remove any type definitons if you are using plain JS.

```javascript
import { AccountsServer } from '@accounts/server'
import { AccountsOauth } from '@accounts/oauth'
import { AccountsServer } from '@accounts/server';
import { AccountsOauth } from '@accounts/oauth';

// We create a new OAuth instance (with at least one provider)
const accountsOauth = new AccountsOauth({
// ... OAuth providers
})
});

// We pass the OAuth instance the AccountsServer service list
const accountsServer = new AccountsServer(...config, {
Expand All @@ -52,8 +52,7 @@ For Nextcloud, read [their docs](https://docs.nextcloud.com/server/19/admin_manu

In the appropriate place of your app, place an "Authenticate via Nextcloud" button that will open a popup window for the user to authenticate via the OAuth provider.

When receiving this code, the client will send it to the AccountsJS-based server, which will verify it with the provider (Nextcloud) itself (we will define the serverside part later).

When receiving this code, the client will send it to the AccountsJS-based server, which will verify it with the provider (Nextcloud) itself (we will define the serverside part later).

```typescript
import qs from 'qs' // https://www.npmjs.com/package/qs
Expand Down Expand Up @@ -81,7 +80,7 @@ function startNextcloudLogin () {
const code = e.data as string
try {
// Send this code to the AccountsJS-based server
await accountsClient.loginWithService('oauth', { provider: 'nextcloud', code })
await accountsClient.loginWithService('oauth', { provider: 'nextcloud', code })
// the 'provider' is key you specify in AccountsOauth config
console.log('User in LoginDialog success', user)
user.value = await accountsClient.getUser()
Expand Down Expand Up @@ -114,61 +113,63 @@ The OAuth provider will redirect to the specified `redirectUri` with a query str
The handler `oauthLoginChannel.onmessage` will use that code to authenticate against your app's accountsjs-based server.

Register a route with your router. Example with vue-router:

```typescript
{ path: '/oauth-callback/:service', component: () => import('components/auth/OAuthCallback.vue') }
```

Define the handler (example based on vue-router):

```typescript
import qs from 'qs'
import qs from 'qs';

export default defineComponent({
setup () {
const { route } = useRouter()
setup() {
const { route } = useRouter();

const service = route.value.params.service
console.log('service:', service)
const service = route.value.params.service;
console.log('service:', service);

onMounted(() => {
const queryParams = qs.parse(window.location.search, { ignoreQueryPrefix: true })
const queryParams = qs.parse(window.location.search, { ignoreQueryPrefix: true });

const loginChannel = new BroadcastChannel('oauthLoginChannel')
loginChannel.postMessage(queryParams.code) // send the code
loginChannel.close()
window.close()
})
const loginChannel = new BroadcastChannel('oauthLoginChannel');
loginChannel.postMessage(queryParams.code); // send the code
loginChannel.close();
window.close();
});

return { ...toRefs(data), service }
}
})
return { ...toRefs(data), service };
},
});
```

### Create the provider definition

In the `oauthLoginChannel.onmessage` handler, we called:

```typescript
accountsClient.loginWithService('oauth', { provider: 'nextcloud', code })
accountsClient.loginWithService('oauth', { provider: 'nextcloud', code });
```

AccountsJS client will send that code to the server, where define a provider:

```typescript
const accountsOauth = new AccountsOauth({
nextcloud: new AccountsNextcloudProvider(),
})
});
```

The provider is defined like this:

```typescript
export class AccountsNextcloudProvider implements OAuthProvider {

/* This method is called when the user returns from the provider with an authorization code */
async authenticate(params: any): Promise<OAuthUser> {
// params.code is the auth code that nextcloud OAuth provides to the client
// params.code is the auth code that nextcloud OAuth provides to the client
// then LoginDialog sends the code here via accountsClient.loginWithService
// it is used here to authenticate against nextcloud and to get the user info

// Ask Nextcloud server if the code is valid, and which user it authenticates
const response = await axios.post(
config.get('accounts.oauth.nextcloud.token-endpoint'), // see: https://docs.nextcloud.com/server/19/admin_manual/configuration_server/oauth2.html
Expand All @@ -182,12 +183,12 @@ export class AccountsNextcloudProvider implements OAuthProvider {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
},
)
}
);

const data = response.data
const token: string = data.access_token
const userID: string = data.user_id
const data = response.data;
const token: string = data.access_token;
const userID: string = data.user_id;

// Optional - query Nextcloud for additional user info:

Expand All @@ -209,19 +210,19 @@ export class AccountsNextcloudProvider implements OAuthProvider {
// This data will be passed to the getRegistrationPayload below, and to createJwtPayload (see optional step later)
return {
id: userID,
//data: userMeta, isAdmin, groups,
}
//data: userMeta, isAdmin, groups,
};
}

/* If your server doesn't know the user yet, this method will be called to get initial user info to be stored in the DB */
async getRegistrationPayload(oauthUser: OAuthUser): Promise<any> {
console.log('OAuth Registration payload for:', oauthUser)
console.log('OAuth Registration payload for:', oauthUser);
return {
// This is nextcloud-specific - TODO: Adapt to your provider
// username: oauthUser.data.id,
// email: oauthUser.data.email,
// displayName: oauthUser.data.displayname,
}
};
}
}
```
Expand All @@ -230,7 +231,6 @@ export class AccountsNextcloudProvider implements OAuthProvider {

This should be enough for a basic OAuth setup to work.


## Optional: Extend the JWT token

In order to add custom fields to the JWT you need to pass a validateNewUser function when you instantiate the `@accounts/password` package.
Expand All @@ -241,7 +241,7 @@ new AccountsServer<ExtendedUserType>(
createJwtPayload: async (data, user) => {
// data is the object returned from AccountsNextcloudProvider.authenticate
// user is the user fetched from the db

const nextcloudData = _.get(user.services, 'nextcloud')
if (!nextcloudData) {
console.log('Extending JWT skipped - no Nextcloud data') // seems to be called sometimes without the data
Expand All @@ -259,4 +259,3 @@ new AccountsServer<ExtendedUserType>(
//... services config
)
```

0 comments on commit 304cc18

Please sign in to comment.