Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding sub in @zemble/auth-apple #95

Merged
merged 2 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/early-wombats-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@zemble/auth-apple": patch
"@zemble/auth-otp": patch
"@zemble/auth": patch
---

Allow overriding sub in @zemble/auth-apple
35 changes: 35 additions & 0 deletions packages/auth-apple/utils/generateToken.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { test, expect } from 'bun:test'
import { decodeJwt } from 'jose'

import { generateBearerTokenFromAppleToken } from './generateToken'
import plugin, { type DefaultAppleToken } from '../plugin'

import type { AppleJwtContents } from './validateIdToken'

test('Should get apple user id as sub', async () => {
// eslint-disable-next-line functional/immutable-data

const encodedToken = await generateBearerTokenFromAppleToken({ sub: 'apple-uid' } as AppleJwtContents, {

})

const decodedToken = decodeJwt(encodedToken)

expect(decodedToken.sub).toBe('apple-uid')
})

test('Should override sub', async () => {
const defaultGenerateTokenContents = plugin.config.generateTokenContents
// eslint-disable-next-line functional/immutable-data
plugin.config.generateTokenContents = () => ({ sub: 'overriden-sub', appleUserId: 'sdfsdf', type: '@zemble/auth-apple' } as DefaultAppleToken)
const encodedToken = await generateBearerTokenFromAppleToken({ sub: 'apple-uid' } as AppleJwtContents, {

})

const decodedToken = decodeJwt(encodedToken)

expect(decodedToken.sub).toBe('overriden-sub')

// eslint-disable-next-line functional/immutable-data
plugin.config.generateTokenContents = defaultGenerateTokenContents
})
7 changes: 5 additions & 2 deletions packages/auth-apple/utils/generateToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ export const generateBearerTokenFromAppleToken = async (
jwtContents: AppleJwtContents,
signUpUserData: AppleUserSignupData | undefined,
) => {
const data = await plugin.config.generateTokenContents(jwtContents, signUpUserData),
sub = 'sub' in data ? data.sub as string : jwtContents.sub

const bearerToken = await signJwt({
data: await plugin.config.generateTokenContents(jwtContents, signUpUserData),
sub,
data,
expiresInSeconds: authPlugin.config.bearerTokenExpiryInSeconds,
sub: jwtContents.sub,
})

return bearerToken
Expand Down
35 changes: 35 additions & 0 deletions packages/auth-otp/graphql/schema.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export type Error = {
readonly message: Scalars['String']['output'];
};

export type LoginConfirmResponse = CodeNotValidError | EmailNotValidError | LoginConfirmSuccessfulResponse | LoginFailedError;

export type LoginConfirmSuccessfulResponse = {
readonly __typename?: 'LoginConfirmSuccessfulResponse';
readonly bearerToken: Scalars['String']['output'];
Expand All @@ -55,6 +57,8 @@ export type LoginFailedError = Error & {
readonly message: Scalars['String']['output'];
};

export type LoginRequestResponse = EmailNotValidError | LoginRequestSuccessResponse;

export type LoginRequestSuccessResponse = {
readonly __typename?: 'LoginRequestSuccessResponse';
readonly success: Scalars['Boolean']['output'];
Expand All @@ -68,8 +72,10 @@ export type Mutation = {
readonly __typename?: 'Mutation';
readonly clear: Scalars['Boolean']['output'];
readonly delete: Scalars['Boolean']['output'];
readonly loginConfirm: LoginConfirmResponse;
readonly loginConfirmWithEmail: LoginConfirmWithEmailResponse;
readonly loginConfirmWithSms: LoginConfirmWithSmsResponse;
readonly loginRequest: LoginRequestResponse;
readonly loginRequestWithEmail: LoginRequestWithEmailResponse;
readonly loginRequestWithSms: LoginRequestWithSmsResponse;
readonly logout: Scalars['DateTime']['output'];
Expand All @@ -90,6 +96,12 @@ export type MutationDeleteArgs = {
};


export type MutationLoginConfirmArgs = {
code: Scalars['String']['input'];
email: Scalars['String']['input'];
};


export type MutationLoginConfirmWithEmailArgs = {
code: Scalars['String']['input'];
email: Scalars['String']['input'];
Expand All @@ -102,6 +114,11 @@ export type MutationLoginConfirmWithSmsArgs = {
};


export type MutationLoginRequestArgs = {
email: Scalars['String']['input'];
};


export type MutationLoginRequestWithEmailArgs = {
email: Scalars['String']['input'];
};
Expand Down Expand Up @@ -268,8 +285,10 @@ export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs

/** Mapping of union types */
export type ResolversUnionTypes<RefType extends Record<string, unknown>> = ResolversObject<{
LoginConfirmResponse: ( CodeNotValidError ) | ( EmailNotValidError ) | ( LoginConfirmSuccessfulResponse ) | ( LoginFailedError );
LoginConfirmWithEmailResponse: ( CodeNotValidError ) | ( EmailNotValidError ) | ( LoginConfirmSuccessfulResponse ) | ( LoginFailedError );
LoginConfirmWithSmsResponse: ( CodeNotValidError ) | ( LoginConfirmSuccessfulResponse ) | ( LoginFailedError ) | ( PhoneNumNotValidError );
LoginRequestResponse: ( EmailNotValidError ) | ( LoginRequestSuccessResponse );
LoginRequestWithEmailResponse: ( EmailNotValidError ) | ( LoginRequestSuccessResponse );
LoginRequestWithSmsResponse: ( LoginRequestSuccessResponse ) | ( PhoneNumNotValidError );
NewTokenResponse: ( NewTokenSuccessResponse ) | ( RefreshTokenInvalidError );
Expand All @@ -291,10 +310,12 @@ export type ResolversTypes = ResolversObject<{
Int: ResolverTypeWrapper<Scalars['Int']['output']>;
JSON: ResolverTypeWrapper<Scalars['JSON']['output']>;
JSONObject: ResolverTypeWrapper<Scalars['JSONObject']['output']>;
LoginConfirmResponse: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['LoginConfirmResponse']>;
LoginConfirmSuccessfulResponse: ResolverTypeWrapper<LoginConfirmSuccessfulResponse>;
LoginConfirmWithEmailResponse: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['LoginConfirmWithEmailResponse']>;
LoginConfirmWithSmsResponse: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['LoginConfirmWithSmsResponse']>;
LoginFailedError: ResolverTypeWrapper<LoginFailedError>;
LoginRequestResponse: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['LoginRequestResponse']>;
LoginRequestSuccessResponse: ResolverTypeWrapper<LoginRequestSuccessResponse>;
LoginRequestWithEmailResponse: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['LoginRequestWithEmailResponse']>;
LoginRequestWithSmsResponse: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['LoginRequestWithSmsResponse']>;
Expand All @@ -318,10 +339,12 @@ export type ResolversParentTypes = ResolversObject<{
Int: Scalars['Int']['output'];
JSON: Scalars['JSON']['output'];
JSONObject: Scalars['JSONObject']['output'];
LoginConfirmResponse: ResolversUnionTypes<ResolversParentTypes>['LoginConfirmResponse'];
LoginConfirmSuccessfulResponse: LoginConfirmSuccessfulResponse;
LoginConfirmWithEmailResponse: ResolversUnionTypes<ResolversParentTypes>['LoginConfirmWithEmailResponse'];
LoginConfirmWithSmsResponse: ResolversUnionTypes<ResolversParentTypes>['LoginConfirmWithSmsResponse'];
LoginFailedError: LoginFailedError;
LoginRequestResponse: ResolversUnionTypes<ResolversParentTypes>['LoginRequestResponse'];
LoginRequestSuccessResponse: LoginRequestSuccessResponse;
LoginRequestWithEmailResponse: ResolversUnionTypes<ResolversParentTypes>['LoginRequestWithEmailResponse'];
LoginRequestWithSmsResponse: ResolversUnionTypes<ResolversParentTypes>['LoginRequestWithSmsResponse'];
Expand Down Expand Up @@ -370,6 +393,10 @@ export interface JsonObjectScalarConfig extends GraphQLScalarTypeConfig<Resolver
name: 'JSONObject';
}

export type LoginConfirmResponseResolvers<ContextType = Zemble.GraphQLContext, ParentType extends ResolversParentTypes['LoginConfirmResponse'] = ResolversParentTypes['LoginConfirmResponse']> = ResolversObject<{
__resolveType: TypeResolveFn<'CodeNotValidError' | 'EmailNotValidError' | 'LoginConfirmSuccessfulResponse' | 'LoginFailedError', ParentType, ContextType>;
}>;

export type LoginConfirmSuccessfulResponseResolvers<ContextType = Zemble.GraphQLContext, ParentType extends ResolversParentTypes['LoginConfirmSuccessfulResponse'] = ResolversParentTypes['LoginConfirmSuccessfulResponse']> = ResolversObject<{
bearerToken?: Resolver<ResolversTypes['String'], ParentType, Zemble.AuthContextWithToken<ContextType>>;
refreshToken?: Resolver<ResolversTypes['String'], ParentType, Zemble.AuthContextWithToken<ContextType>>;
Expand All @@ -389,6 +416,10 @@ export type LoginFailedErrorResolvers<ContextType = Zemble.GraphQLContext, Paren
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}>;

export type LoginRequestResponseResolvers<ContextType = Zemble.GraphQLContext, ParentType extends ResolversParentTypes['LoginRequestResponse'] = ResolversParentTypes['LoginRequestResponse']> = ResolversObject<{
__resolveType: TypeResolveFn<'EmailNotValidError' | 'LoginRequestSuccessResponse', ParentType, ContextType>;
}>;

export type LoginRequestSuccessResponseResolvers<ContextType = Zemble.GraphQLContext, ParentType extends ResolversParentTypes['LoginRequestSuccessResponse'] = ResolversParentTypes['LoginRequestSuccessResponse']> = ResolversObject<{
success?: Resolver<ResolversTypes['Boolean'], ParentType, Zemble.AuthContextWithToken<ContextType>>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
Expand All @@ -405,8 +436,10 @@ export type LoginRequestWithSmsResponseResolvers<ContextType = Zemble.GraphQLCon
export type MutationResolvers<ContextType = Zemble.GraphQLContext, ParentType extends ResolversParentTypes['Mutation'] = ResolversParentTypes['Mutation']> = ResolversObject<{
clear?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType, RequireFields<MutationClearArgs, 'prefix'>>;
delete?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType, RequireFields<MutationDeleteArgs, 'key' | 'prefix'>>;
loginConfirm?: Resolver<ResolversTypes['LoginConfirmResponse'], ParentType, Zemble.AuthContextWithToken<ContextType>, RequireFields<MutationLoginConfirmArgs, 'code' | 'email'>>;
loginConfirmWithEmail?: Resolver<ResolversTypes['LoginConfirmWithEmailResponse'], ParentType, Zemble.AuthContextWithToken<ContextType>, RequireFields<MutationLoginConfirmWithEmailArgs, 'code' | 'email'>>;
loginConfirmWithSms?: Resolver<ResolversTypes['LoginConfirmWithSmsResponse'], ParentType, Zemble.AuthContextWithToken<ContextType>, RequireFields<MutationLoginConfirmWithSmsArgs, 'code' | 'phoneNumberWithCountryCode'>>;
loginRequest?: Resolver<ResolversTypes['LoginRequestResponse'], ParentType, Zemble.AuthContextWithToken<ContextType>, RequireFields<MutationLoginRequestArgs, 'email'>>;
loginRequestWithEmail?: Resolver<ResolversTypes['LoginRequestWithEmailResponse'], ParentType, Zemble.AuthContextWithToken<ContextType>, RequireFields<MutationLoginRequestWithEmailArgs, 'email'>>;
loginRequestWithSms?: Resolver<ResolversTypes['LoginRequestWithSmsResponse'], ParentType, Zemble.AuthContextWithToken<ContextType>, RequireFields<MutationLoginRequestWithSmsArgs, 'phoneNumberWithCountryCode'>>;
logout?: Resolver<ResolversTypes['DateTime'], ParentType, ContextType>;
Expand Down Expand Up @@ -454,10 +487,12 @@ export type Resolvers<ContextType = Zemble.GraphQLContext> = ResolversObject<{
Error?: ErrorResolvers<ContextType>;
JSON?: GraphQLScalarType;
JSONObject?: GraphQLScalarType;
LoginConfirmResponse?: LoginConfirmResponseResolvers<ContextType>;
LoginConfirmSuccessfulResponse?: LoginConfirmSuccessfulResponseResolvers<ContextType>;
LoginConfirmWithEmailResponse?: LoginConfirmWithEmailResponseResolvers<ContextType>;
LoginConfirmWithSmsResponse?: LoginConfirmWithSmsResponseResolvers<ContextType>;
LoginFailedError?: LoginFailedErrorResolvers<ContextType>;
LoginRequestResponse?: LoginRequestResponseResolvers<ContextType>;
LoginRequestSuccessResponse?: LoginRequestSuccessResponseResolvers<ContextType>;
LoginRequestWithEmailResponse?: LoginRequestWithEmailResponseResolvers<ContextType>;
LoginRequestWithSmsResponse?: LoginRequestWithSmsResponseResolvers<ContextType>;
Expand Down